home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / GCC 1.37.1r14 / usr / gcc-1.37.1r14 / (gcc-1.37.π) / expr.c < prev    next >
Encoding:
Text File  |  1993-10-01  |  171.4 KB  |  3,112 lines  |  [TEXT/KAHL]

  1. o be output
  2.    for POSTINCREMENT_EXPR expressions, etc.  */
  3.  
  4. static rtx pending_chain;
  5.  
  6. /* Queue up to increment (or change) VAR later.  BODY says how:
  7.    BODY should be the same thing you would pass to emit_insn
  8.    to increment right away.  It will go to emit_insn later on.
  9.  
  10.    The value is a QUEUED expression to be used in place of VAR
  11.    where you want to guarantee the pre-incrementation value of VAR.  */
  12.  
  13. static rtx
  14. enqueue_insn (var, body)
  15.      rtx var, body;
  16. {
  17.   pending_chain = gen_rtx (QUEUED, GET_MODE (var),
  18.                var, 0, 0, body, pending_chain);
  19.   return pending_chain;
  20. }
  21.  
  22. /* Use protect_from_queue to convert a QUEUED expression
  23.    into something that you can put immediately into an instruction.
  24.    If the queued incrementation has not happened yet,
  25.    protect_from_queue returns the variable itself.
  26.    If the incrementation has happened, protect_from_queue returns a temp
  27.    that contains a copy of the old value of the variable.
  28.  
  29.    Any time an rtx which might possibly be a QUEUED is to be put
  30.    into an instruction, it must be passed through protect_from_queue first.
  31.    QUEUED expressions are not meaningful in instructions.
  32.  
  33.    Do not pass a value through protect_from_queue and then hold
  34.    on to it for a while before putting it in an instruction!
  35.    If the queue is flushed in between, incorrect code will result.  */
  36.  
  37. rtx
  38. protect_from_queue (x, modify)
  39.      register rtx x;
  40.      int modify;
  41. {
  42.   register RTX_CODE code = GET_CODE (x);
  43.   if (code != QUEUED)
  44.     {
  45.       /* A special hack for read access to (MEM (QUEUED ...))
  46.      to facilitate use of autoincrement.
  47.      Make a copy of the contents of the memory location
  48.      rather than a copy of the address.  */
  49.       if (code == MEM && GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
  50.     {
  51.       register rtx y = XEXP (x, 0);
  52.       XEXP (x, 0) = QUEUED_VAR (y);
  53.       if (QUEUED_INSN (y))
  54.         {
  55.           register rtx temp = gen_reg_rtx (GET_MODE (x));
  56.           emit_insn_before (gen_move_insn (temp, x),
  57.                 QUEUED_INSN (y));
  58.           return temp;
  59.         }
  60.       return x;
  61.     }
  62.       /* Otherwise, recursively protect the subexpressions of all
  63.      the kinds of rtx's that can contain a QUEUED.  */
  64.       if (code == MEM)
  65.     XEXP (x, 0) = protect_from_queue (XEXP (x, 0), 0);
  66.       else if (code == PLUS || code == MULT)
  67.     {
  68.       XEXP (x, 0) = protect_from_queue (XEXP (x, 0), 0);
  69.       XEXP (x, 1) = protect_from_queue (XEXP (x, 1), 0);
  70.     }
  71.       return x;
  72.     }
  73.   /* If the increment has not happened, use the variable itself.  */
  74.   if (QUEUED_INSN (x) == 0)
  75.     return QUEUED_VAR (x);
  76.   /* If the increment has happened and a pre-increment copy exists,
  77.      use that copy.  */
  78.   if (QUEUED_COPY (x) != 0)
  79.     return QUEUED_COPY (x);
  80.   /* The increment has happened but we haven't set up a pre-increment copy.
  81.      Set one up now, and use it.  */
  82.   QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));
  83.   emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),
  84.             QUEUED_INSN (x));
  85.   return QUEUED_COPY (x);
  86. }
  87.  
  88. /* Return nonzero if X contains a QUEUED expression:
  89.    if it contains anything that will be altered by a queued increment.
  90.    We handle only combinations of MEM, PLUS, MINUS and MULT operators
  91.    since memory addresses generally contain only those.  */
  92.  
  93. static int
  94. queued_subexp_p (x)
  95.      rtx x;
  96. {
  97.   register enum rtx_code code = GET_CODE (x);
  98.   switch (code)
  99.     {
  100.     case QUEUED:
  101.       return 1;
  102.     case MEM:
  103.       return queued_subexp_p (XEXP (x, 0));
  104.     case MULT:
  105.     case PLUS:
  106.     case MINUS:
  107.       return queued_subexp_p (XEXP (x, 0))
  108.     || queued_subexp_p (XEXP (x, 1));
  109.     }
  110.   return 0;
  111. }
  112.  
  113. /* Perform all the pending incrementations.  */
  114.  
  115. void
  116. emit_queue ()
  117. {
  118.   register rtx p;
  119.   while (p = pending_chain)
  120.     {
  121.       QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));
  122.       pending_chain = QUEUED_NEXT (p);
  123.     }
  124. }
  125.  
  126. static void
  127. init_queue ()
  128. {
  129.   if (pending_chain)
  130.     abort ();
  131. }
  132.  
  133. /* Copy data from FROM to TO, where the machine modes are not the same.
  134.    Both modes may be integer, or both may be floating.
  135.    UNSIGNEDP should be nonzero if FROM is an unsigned type.
  136.    This causes zero-extension instead of sign-extension.  */
  137.  
  138. void
  139. convert_move (to, from, unsignedp)
  140.      register rtx to, from;
  141.      int unsignedp;
  142. {
  143.   enum machine_mode to_mode = GET_MODE (to);
  144.   enum machine_mode from_mode = GET_MODE (from);
  145.   int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
  146.   int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
  147.   int extending = (int) to_mode > (int) from_mode;
  148.  
  149.   to = protect_from_queue (to, 1);
  150.   from = protect_from_queue (from, 0);
  151.  
  152.   if (to_real != from_real)
  153.     abort ();
  154.  
  155.   if (to_mode == from_mode
  156.       || (from_mode == VOIDmode && CONSTANT_P (from)))
  157.     {
  158.       emit_move_insn (to, from);
  159.       return;
  160.     }
  161.  
  162.   if (to_real)
  163.     {
  164. #ifdef APPLE_HAX
  165.       if (to_mode == XFmode)
  166.     {
  167. #ifdef HAVE_extendsfxf2
  168.       if (from_mode == SFmode && HAVE_extendsfxf2 && extending)
  169.         {
  170.           emit_unop_insn (CODE_FOR_extendsfxf2, to, from, UNKNOWN);
  171.           return;
  172.         }
  173. #endif
  174. #ifdef HAVE_extenddfxf2
  175.       if (from_mode == DFmode && HAVE_extenddfxf2 && extending)
  176.         {
  177.           emit_unop_insn (CODE_FOR_extenddfxf2, to, from, UNKNOWN);
  178.           return;
  179.         }
  180. #endif
  181.       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ((from_mode == SFmode)
  182.                               ? "__extendsfxf2"
  183.                               : "__extenddfxf2")),
  184.                  0, GET_MODE (to), 1, from, from_mode);
  185.       emit_move_insn (to, hard_libcall_value (GET_MODE (to)));
  186.       return;
  187.     }
  188.       /* OK, now to_mode is sf or df, but from_mode might still be xf */
  189.       if (from_mode == XFmode)
  190.     {
  191. #ifdef HAVE_truncxfsf2
  192.       if (HAVE_truncxfsf2 && to_mode == SFmode)
  193.         {
  194.           emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
  195.           return;
  196.         }
  197. #endif
  198. #ifdef HAVE_truncxfdf2
  199.       if (HAVE_truncxfdf2 && to_mode == DFmode)
  200.         {
  201.           emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
  202.           return;
  203.         }
  204. #endif
  205.       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ((to_mode == SFmode)
  206.                               ? "__truncxfsf2"
  207.                               : "__truncxfdf2")),
  208.                  0, GET_MODE (to), 1, from, from_mode);
  209.       emit_move_insn (to, hard_libcall_value (GET_MODE (to)));
  210.       return;
  211.         }
  212.       /* all the longer modes should be taken care of now */
  213. #ifdef HAVE_extendsfdf2
  214.       if (HAVE_extendsfdf2 && extending)
  215.     {
  216.       emit_unop_insn (CODE_FOR_extendsfdf2, to, from, UNKNOWN);
  217.       return;
  218.     }
  219. #else
  220.       /* try using xf as an intermediary */
  221. #if defined(HAVE_extendsfxf2) && defined(HAVE_truncxfdf2)
  222.       if (HAVE_extendsfxf2 && HAVE_truncxfdf2 && extending)
  223.     {
  224.       rtx tmp = gen_reg_rtx(XFmode);
  225.  
  226.       emit_unop_insn (CODE_FOR_extendsfxf2, tmp, from, UNKNOWN);
  227.       emit_unop_insn (CODE_FOR_truncxfdf2, to, tmp, UNKNOWN);
  228.       return;
  229.         }
  230. #endif
  231. #endif /* HAVE_extendsfdf2 */
  232. #ifdef HAVE_truncdfsf2
  233.       if (HAVE_truncdfsf2 && ! extending)
  234.     {
  235.       emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
  236.       return;
  237.     }
  238. #else
  239.       /* try using xf as an intermediary */
  240. #if defined(HAVE_extenddfxf2) && defined(HAVE_truncxfsf2)
  241.       if (HAVE_extenddfxf2 && HAVE_truncxfsf2 && ! extending)
  242.     {
  243.       rtx tmp = gen_reg_rtx(XFmode);
  244.  
  245.       emit_unop_insn (CODE_FOR_extenddfxf2, tmp, from, UNKNOWN);
  246.       emit_unop_insn (CODE_FOR_truncxfsf2, to, tmp, UNKNOWN);
  247.       return;
  248.         }
  249. #endif
  250. #endif /* HAVE_truncdfsf2 */
  251. #else /* n APPLE_HAX */
  252. #ifdef HAVE_extendsfdf2
  253.       if (HAVE_extendsfdf2 && extending)
  254.     {
  255.       emit_unop_insn (CODE_FOR_extendsfdf2, to, from, UNKNOWN);
  256.       return;
  257.     }
  258. #endif
  259. #ifdef HAVE_truncdfsf2
  260.       if (HAVE_truncdfsf2 && ! extending)
  261.     {
  262.       emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
  263.       return;
  264.     }
  265. #endif
  266. #endif /* APPLE_HAX */
  267.       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, (extending
  268.                               ? "__extendsfdf2"
  269.                               : "__truncdfsf2")), 0,
  270.              GET_MODE (to), 1,
  271.              from,  (extending ? SFmode : DFmode));
  272.       emit_move_insn (to, hard_libcall_value (GET_MODE (to)));
  273.       return;
  274.     }
  275.  
  276.   /* Now both modes are integers.  */
  277.  
  278.   if (to_mode == DImode)
  279.     {
  280.       if (unsignedp)
  281.     {
  282. #ifdef HAVE_zero_extendsidi2
  283.       if (HAVE_zero_extendsidi2 && from_mode == SImode)
  284.         emit_unop_insn (CODE_FOR_zero_extendsidi2, to, from, ZERO_EXTEND);
  285.       else
  286. #endif
  287. #ifdef HAVE_zero_extendhidi2
  288.       if (HAVE_zero_extendhidi2 && from_mode == HImode)
  289.         emit_unop_insn (CODE_FOR_zero_extendhidi2, to, from, ZERO_EXTEND);
  290.       else
  291. #endif
  292. #ifdef HAVE_zero_extendqidi2
  293.       if (HAVE_zero_extendqidi2 && from_mode == QImode)
  294.         emit_unop_insn (CODE_FOR_zero_extendqidi2, to, from, ZERO_EXTEND);
  295.       else
  296. #endif
  297. #ifdef HAVE_zero_extendsidi2
  298.       if (HAVE_zero_extendsidi2)
  299.         {
  300.           convert_move (gen_lowpart (SImode, to), from, unsignedp);
  301.           emit_unop_insn (CODE_FOR_zero_extendsidi2, to,
  302.                   gen_lowpart (SImode, to), ZERO_EXTEND);
  303.         }
  304.       else
  305. #endif
  306.         {
  307.           emit_insn (gen_rtx (CLOBBER, VOIDmode, to));
  308.           convert_move (gen_lowpart (SImode, to), from, unsignedp);
  309.           emit_clr_insn (gen_highpart (SImode, to));
  310.         }
  311.     }
  312. #ifdef HAVE_extendsidi2
  313.       else if (HAVE_extendsidi2 && from_mode == SImode)
  314.     emit_unop_insn (CODE_FOR_extendsidi2, to, from, SIGN_EXTEND);
  315. #endif
  316. #ifdef HAVE_extendhidi2
  317.       else if (HAVE_extendhidi2 && from_mode == HImode)
  318.     emit_unop_insn (CODE_FOR_extendhidi2, to, from, SIGN_EXTEND);
  319. #endif
  320. #ifdef HAVE_extendqidi2
  321.       else if (HAVE_extendqidi2 && from_mode == QImode)
  322.     emit_unop_insn (CODE_FOR_extendqidi2, to, from, SIGN_EXTEND);
  323. #endif
  324. #ifdef HAVE_extendsidi2
  325.       else if (HAVE_extendsidi2)
  326.     {
  327.       convert_move (gen_lowpart (SImode, to), from, unsignedp);
  328.       emit_unop_insn (CODE_FOR_extendsidi2, to,
  329.               gen_lowpart (SImode, to), SIGN_EXTEND);
  330.     }
  331. #endif
  332. #ifdef HAVE_slt
  333.       else if (HAVE_slt && insn_operand_mode[(int) CODE_FOR_slt][0] == SImode)
  334.     {
  335.       emit_insn (gen_rtx (CLOBBER, VOIDmode, to));
  336.       convert_move (gen_lowpart (SImode, to), from, unsignedp);
  337.       emit_insn (gen_slt (gen_highpart (SImode, to)));
  338.     }
  339. #endif
  340.       else
  341.     {
  342.       register rtx label = gen_label_rtx ();
  343.  
  344.       emit_insn (gen_rtx (CLOBBER, VOIDmode, to));
  345.       emit_clr_insn (gen_highpart (SImode, to));
  346.       convert_move (gen_lowpart (SImode, to), from, unsignedp);
  347.       emit_cmp_insn (gen_lowpart (SImode, to),
  348.              gen_rtx (CONST_INT, VOIDmode, 0),
  349.              0, 0, 0);
  350.       NO_DEFER_POP;
  351.       emit_jump_insn (gen_bge (label));
  352.       expand_unop (SImode, one_cmpl_optab,
  353.                gen_highpart (SImode, to), gen_highpart (SImode, to),
  354.                1);
  355.       emit_label (label);
  356.       OK_DEFER_POP;
  357.     }
  358.       return;
  359.     }
  360.  
  361.   if (from_mode == DImode)
  362.     {
  363.       convert_move (to, gen_lowpart (SImode, from), 0);
  364.       return;
  365.     }
  366.  
  367.   /* Now follow all the conversions between integers
  368.      no more than a word long.  */
  369.  
  370.   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
  371.   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
  372.       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
  373.                 GET_MODE_BITSIZE (from_mode))
  374.       && ((GET_CODE (from) == MEM
  375.        && ! MEM_VOLATILE_P (from)
  376.        && ! mode_dependent_address_p (XEXP (from, 0)))
  377.       || GET_CODE (from) == REG
  378.       || GET_CODE (from) == SUBREG))
  379.     {
  380.       emit_move_insn (to, gen_lowpart (to_mode, from));
  381.       return;
  382.     }
  383.  
  384.   if (to_mode == SImode && from_mode == HImode)
  385.     {
  386.       if (unsignedp)
  387.     {
  388. #ifdef HAVE_zero_extendhisi2
  389.       if (HAVE_zero_extendhisi2)
  390.         emit_unop_insn (CODE_FOR_zero_extendhisi2, to, from, ZERO_EXTEND);
  391.       else
  392. #endif
  393.         abort ();
  394.     }
  395.       else
  396.     {
  397. #ifdef HAVE_extendhisi2
  398.       if (HAVE_extendhisi2)
  399.         emit_unop_insn (CODE_FOR_extendhisi2, to, from, SIGN_EXTEND);
  400.       else
  401. #endif
  402.         abort ();
  403.     }
  404.       return;
  405.     }
  406.  
  407.   if (to_mode == SImode && from_mode == QImode)
  408.     {
  409.       if (unsignedp)
  410.     {
  411. #ifdef HAVE_zero_extendqisi2
  412.       if (HAVE_zero_extendqisi2)
  413.         {
  414.           emit_unop_insn (CODE_FOR_zero_extendqisi2, to, from, ZERO_EXTEND);
  415.           return;
  416.         }
  417. #endif
  418. #if defined (HAVE_zero_extendqihi2) && defined (HAVE_extendhisi2)
  419.       if (HAVE_zero_extendqihi2 && HAVE_extendhisi2)
  420.         {
  421.           register rtx temp = gen_reg_rtx (HImode);
  422.           emit_unop_insn (CODE_FOR_zero_extendqihi2, temp, from, ZERO_EXTEND);
  423.           emit_unop_insn (CODE_FOR_extendhisi2, to, temp, SIGN_EXTEND);
  424.           return;
  425.         }
  426. #endif
  427.     }
  428.       else
  429.     {
  430. #ifdef HAVE_extendqisi2
  431.       if (HAVE_extendqisi2)
  432.         {
  433.           emit_unop_insn (CODE_FOR_extendqisi2, to, from, SIGN_EXTEND);
  434.           return;
  435.         }
  436. #endif
  437. #if defined (HAVE_exten>reverse) data->offset -= size;
  438.  
  439.       to1 = (data->autinc_to
  440.          ? gen_rtx (MEM, mode, data->to_addr)
  441.          : change_address (data->to, mode,
  442.                    plus_constant (data->to_addr, data->offset)));
  443.       from1 =
  444.     (data->autinc_from
  445.      ? gen_rtx (MEM, mode, data->from_addr)
  446.      : change_address (data->from, mode,
  447.                plus_constant (data->from_addr, data->offset)));
  448.  
  449. #ifdef HAVE_PRE_DECREMENT
  450.       if (data->explicit_inc_to < 0)
  451.     emit_insn (gen_sub2_insn (data->to_addr,
  452.                   gen_rtx (CONST_INT, VOIDmode, size)));
  453.       if (data->explicit_inc_from < 0)
  454.     emit_insn (gen_sub2_insn (data->from_addr,
  455.                   gen_rtx (CONST_INT, VOIDmode, size)));
  456. #endif
  457.  
  458.       emit_insn ((*genfun) (to1, from1));
  459. #ifdef HAVE_POST_INCREMENT
  460.       if (data->explicit_inc_to > 0)
  461.     emit_insn (gen_add2_insn (data->to_addr,
  462.                   gen_rtx (CONST_INT, VOIDmode, size)));
  463.       if (data->explicit_inc_from > 0)
  464.     emit_insn (gen_add2_insn (data->from_addr,
  465.                   gen_rtx (CONST_INT, VOIDmode, size)));
  466. #endif
  467.  
  468.       if (! data->reverse) data->offset += size;
  469.  
  470.       data->len -= size;
  471.     }
  472. }
  473.  
  474. /* Emit code to move a block Y to a block X.
  475.    This may be done with string-move instructions,
  476.    with multiple scalar move instructions, or with a library call.
  477.  
  478.    Both X and Y must be MEM rtx's (perhaps inside VOLATILE)
  479.    with mode BLKmode.
  480.    SIZE is an rtx that says how long they are.
  481.    ALIGN is the maximum alignment we can assume they have,
  482.    measured in bytes.  */
  483.  
  484. static void
  485. emit_block_move (x, y, size, align)
  486.      rtx x, y;
  487.      rtx size;
  488.      int align;
  489. {
  490.   if (GET_MODE (x) != BLKmode)
  491.     abort ();
  492.  
  493.   if (GET_MODE (y) != BLKmode)
  494.     abort ();
  495.  
  496.   x = protect_from_queue (x, 1);
  497.   y = protect_from_queue (y, 0);
  498.  
  499.   if (GET_CODE (x) != MEM)
  500.     abort ();
  501.   if (GET_CODE (y) != MEM)
  502.     abort ();
  503.   if (size == 0)
  504.     abort ();
  505.  
  506.   if (GET_CODE (size) == CONST_INT
  507.       && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)
  508.       < MOVE_RATIO))
  509.     move_by_pieces (x, y, INTVAL (size), align);
  510.   else
  511.     {
  512.       /* Try the most limited insn first, because there's no point
  513.      including more than one in the machine description unless
  514.      the more limited one has some advantage.  */
  515. #ifdef HAVE_movstrqi
  516.       if (HAVE_movstrqi
  517.       && GET_CODE (size) == CONST_INT
  518.       && ((unsigned) INTVAL (size)
  519.           < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
  520.     {
  521.       emit_insn (gen_movstrqi (x, y, size,
  522.                    gen_rtx (CONST_INT, VOIDmode, align)));
  523.       return;
  524.     }
  525. #endif
  526. #ifdef HAVE_movstrhi
  527.       if (HAVE_movstrhi
  528.       && GET_CODE (size) == CONST_INT
  529.       && ((unsigned) INTVAL (size)
  530.           < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
  531.     {
  532.       emit_insn (gen_movstrhi (x, y, size,
  533.                    gen_rtx (CONST_INT, VOIDmode, align)));
  534.       return;
  535.     }
  536. #endif
  537. #ifdef HAVE_movstrsi
  538.       if (HAVE_movstrsi)
  539.     {
  540.       emit_insn (gen_movstrsi (x, y, size,
  541.                    gen_rtx (CONST_INT, VOIDmode, align)));
  542.       return;
  543.     }
  544. #endif
  545.  
  546. #ifdef TARGET_MEM_FUNCTIONS
  547.       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
  548.              VOIDmode, 3, XEXP (x, 0), Pmode,
  549.              XEXP (y, 0), Pmode,
  550.              size, Pmode);
  551. #else
  552.       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
  553.              VOIDmode, 3, XEXP (y, 0), Pmode,
  554.              XEXP (x, 0), Pmode,
  555.              size, Pmode);
  556. #endif
  557.     }
  558. }
  559.  
  560. /* Copy all or part of a BLKmode value X into registers starting at REGNO.
  561.    The number of registers to be filled is NREGS.  */
  562.  
  563. static void
  564. move_block_to_reg (regno, x, nregs)
  565.      int regno;
  566.      rtx x;
  567.      int nregs;
  568. {
  569.   int i;
  570.   if (GET_CODE (x) == CONST_DOUBLE && x != dconst0_rtx)
  571.     x = force_const_double_mem (x);
  572.   for (i = 0; i < nregs; i++)
  573.     {
  574.       if (GET_CODE (x) == REG)
  575.     emit_move_insn (gen_rtx (REG, SImode, regno + i),
  576.             gen_rtx (SUBREG, SImode, x, i));
  577.       else if (x == dconst0_rtx)
  578.     emit_move_insn (gen_rtx (REG, SImode, regno + i),
  579.             const0_rtx);
  580.       else
  581.     emit_move_insn (gen_rtx (REG, SImode, regno + i),
  582.             gen_rtx (MEM, SImode,
  583.                  memory_address (SImode,
  584.                          plus_constant (XEXP (x, 0),
  585.                                 i * GET_MODE_SIZE (SImode)))));
  586.     }
  587. }
  588.  
  589. /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
  590.    The number of regREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field);
  591.       mode = DECL_MODE (field);
  592.       unsignedp = TREE_UNSIGNED (field);
  593.  
  594.       bitpos = DECL_OFFSET (field);
  595.  
  596.       store_field (target, bitsize, bitpos, mode, TREE_VALUE (elt),
  597.                /* The alignment of TARGET is
  598.               at least what its type requires.  */
  599.                VOIDmode, 0,
  600.                TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  601.     }
  602.     }
  603.   else if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
  604.     {
  605.       register tree elt;
  606.       register int i;
  607.       tree domain = TYPE_DOMAIN (TREE_TYPE (exp));
  608.       int minelt = TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain));
  609.       int maxelt = TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain));
  610.       tree elttype = TREE_TYPE (TREE_TYPE (exp));
  611.  
  612.       /* If the constructor has fewer fields than the structure,
  613.      clear the whole structure first.  */
  614.  
  615.       if (list_length (CONSTRUCTOR_ELTS (exp)) < maxelt - minelt + 1)
  616.     clear_storage (target, maxelt - minelt + 1);
  617.       else
  618.     /* Inform later passes that the old value is dead.  */
  619.     emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
  620.  
  621.       /* Store each element of the constructor into
  622.      the corresponding element of TARGET, determined
  623.      by counting the elements.  */
  624.       for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
  625.        elt;
  626.        elt = TREE_CHAIN (elt), i++)
  627.     {
  628.       register enum machine_mode mode;
  629.       int bitsize;
  630.       int bitpos;
  631.       int unsignedp;
  632.  
  633.       mode = TYPE_MODE (elttype);
  634.       bitsize = GET_MODE_BITSIZE (mode);
  635.       unsignedp = TREE_UNSIGNED (elttype);
  636.  
  637.       bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype))
  638.             * TYPE_SIZE_UNIT (elttype));
  639.  
  640.       store_field (target, bitsize, bitpos, mode, TREE_VALUE (elt),
  641.                /* The alignment of TARGET is
  642.               at least what its type requires.  */
  643.                VOIDmode, 0,
  644.                TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  645.     }
  646.     }
  647. }
  648.  
  649. /* Store the value of EXP (an expression tree)
  650.    into a subfield of TARGET which has mode MODE and occupies
  651.    BITSIZE bits, starting BITPOS bits from the start of TARGET.
  652.  
  653.    If VALUE_MODE is VOIDmode, return nothing in particular.
  654.    UNSIGNEDP is not used in this case.
  655.  
  656.    Otherwise, return an rtx for the value stored.  This rtx
  657.    has mode VALUE_MODE if that is convenient to do.
  658.    In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
  659.  
  660.    ALIGN is the alignment that TARGET is known to have, measured in bytes.  */
  661.  
  662. static rtx
  663. store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, align)
  664.      rtx target;
  665.      int bitsize, bitpos;
  666.      enum machine_mode mode;
  667.      tree exp;
  668.      enum machine_mode value_mode;
  669.      int unsignedp;
  670.      int align;
  671. {
  672.   /* If the structure is in a register or if the component
  673.      is a bit field, we cannot use addressing to access it.
  674.      Use bit-field techniques or SUBREG to store in it.  */
  675.  
  676.   if (mode == BImode || GET_CODE (target) == REG
  677.       || GET_CODE (target) == SUBREG)
  678.     {
  679.       store_bit_field (target, bitsize, bitpos,
  680.                mode,
  681.                expand_expr (exp, 0, VOIDmode, 0),
  682.                align);
  683.       if (value_mode != VOIDmode)
  684.     return extract_bit_field (target, bitsize, bitpos, unsignedp,
  685.                   0, value_mode, 0, align);
  686.       return const0_rtx;
  687.     }
  688.   else
  689.     {
  690.       rtx addr = XEXP (target, 0);
  691.       rtx to_rtx;
  692.  
  693.       /* If a value is wanted, it must be the lhs;
  694.      so make the address stable for multiple use.  */
  695.  
  696.       if (value_mode != VOIDmode && GET_CODE (addr) != REG
  697.       && ! CONSTANT_ADDRESS_P (addr))
  698.     addr = copy_to_reg (addr);
  699.  
  700.       /* Now build a reference to just the desired component.  */
  701.  
  702.       to_rtx = change_address (target, mode,
  703.                    plus_constant (addr,
  704.                           (bitpos / BITS_PER_UNIT)));
  705.       MEM_IN_STRUCT_P (to_rtx) = 1;
  706.  
  707.       return store_expr (exp, to_rtx, value_mode != VOIDmode);
  708.     }
  709. }
  710.  
  711. /* Given an rtx VALUE that may contain additions and multiplications,
  712.    return an equivalent value that just refers to a register or memory.
  713.    This is done by generating instructions to perform the arithmetic
  714.    and returning a pseudo-register containing the value.  */
  715.  
  716. rtx
  717. force_operand (value, target)
  718.      rtx value, target;
  719. {
  720.   regNCE (exp) == const0_rtx)
  721.     abort ();
  722.       emit_insns (RTL_EXPR_SEQUENCE (exp));
  723.       RTL_EXPR_SEQUENCE (exp) = const0_rtx;
  724.       return RTL_EXPR_RTL (exp);
  725.  
  726.     case CONSTRUCTOR:
  727.       /* All elts simple constants => refer to a constant in memory.  */
  728.       if (TREE_STATIC (exp))
  729.     /* For aggregate types with non-BLKmode modes,
  730.        this should ideally construct a CONST_INT.  */
  731.     {
  732.       rtx constructor = output_constant_def (exp);
  733.       if (! memory_address_p (GET_MODE (constructor),
  734.                   XEXP (constructor, 0)))
  735.         constructor = change_address (constructor, VOIDmode,
  736.                       XEXP (constructor, 0));
  737.       return constructor;
  738.     }
  739.  
  740.       if (ignore)
  741.     {
  742.       tree elt;
  743.       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
  744.         expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
  745.       return const0_rtx;
  746.     }
  747.       else
  748.     {
  749.       if (target == 0)
  750.         target = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)),
  751.                   get_structure_value_addr (expr_size (exp)));
  752.       store_expr (exp, target, 0);
  753.       return target;
  754.     }
  755.  
  756.     case INDIRECT_REF:
  757.       {
  758.     tree exp1 = TREE_OPERAND (exp, 0);
  759.     tree exp2;
  760.  
  761.     /* A SAVE_EXPR as the address in an INDIRECT_EXPR is generated
  762.        for  *PTR += ANYTHING  where PTR is put inside the SAVE_EXPR.
  763.        This code has the same general effect as simply doing
  764.        expand_expr on the save expr, except that the expression PTR
  765.        is computed for use as a memory address.  This means different
  766.        code, suitable for indexing, may be generated.  */
  767.     if (TREE_CODE (exp1) == SAVE_EXPR
  768.         && SAVE_EXPR_RTL (exp1) == 0
  769.         && TREE_CODE (exp2 = TREE_OPERAND (exp1, 0)) != ERROR_MARK
  770.         && TYPE_MODE (TREE_TYPE (exp1)) == Pmode
  771.         && TYPE_MODE (TREE_TYPE (exp2)) == Pmode)
  772.       {
  773.         temp = expand_expr (TREE_OPERAND (exp1, 0), 0, VOIDmode, EXPAND_SUM);
  774.         op0 = memory_address (mode, temp);
  775.         op0 = copy_all_regs (op0);
  776.         SAVE_EXPR_RTL (exp1) = op0;
  777.       }
  778.     else
  779.       {
  780.         op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, EXPAND_SUM);
  781.         op0 = memory_address (mode, op0);
  782.       }
  783.       }
  784.       temp = gen_rtx (MEM, mode, op0);
  785.       /* If address was computed by addition,
  786.      mark this as an element of an aggregate.  */
  787.       if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
  788.       || (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR
  789.           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == PLUS_EXPR))
  790.     MEM_IN_STRUCT_P (temp) = 1;
  791.       MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) || flag_volatile;
  792.       RTX_UNCHANGING_P (temp) = TREE_READONLY (exp);
  793.       return temp;
  794.  
  795.     case ARRAY_REF:
  796.       if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
  797.       || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST)
  798.     {
  799.       /* Nonconstant array index or nonconstant element size.
  800.          Generate the tree for *(&array+index) and expand that,
  801.          except do it in a language-independent way
  802.          and don't complain about non-lvalue arrays.
  803.          `mark_addressable' should already have been called
  804.          for any array for which this case will be reached.  */
  805.  
  806.       tree array_adr = build (ADDR_EXPR, TYPE_POINTER_TO (type),
  807.                   TREE_OPERAND (exp, 0));
  808.       tree index = TREE_OPERAND (exp, 1);
  809.       tree elt;
  810.  
  811.       /* Convert the integer argument to a type the same size as a pointer
  812.          so the multiply won't overflow spuriously.  */
  813.       if (TYPE_PRECISION (TREE_TYPE (index)) != POINTER_SIZE)
  814.         index = convert (type_for_size (POINTER_SIZE, 0), index);
  815.  
  816.       /* The array address isn't volatile even if the array is.  */
  817.       TREE_VOLATILE (array_adr) = 0;
  818.  
  819.       elt = build (INDIRECT_REF, type,
  820.                fold (build (PLUS_EXPR, TYPE_POINTER_TO (type),
  821.                     array_adr,
  822.                     fold (build (MULT_EXPR,
  823.                          TYPE_POINTER_TO (type),
  824.                          index, size_in_bytes (type))))));
  825.  
  826.       return expand_expr (elt, target, tmode, modifier);
  827.     }
  828.  
  829.       /* Fold an expression like: "foo"[2].
  830.      This is not done in fold so it won't happen inside &.  */
  831.       {
  832.     int i;
  833.     tree arg0 = TREE_OPERAND (exp, 0);
  834.     tree arg1 = TREE_OPERAND (exp, 1);
  835.  
  836.     if (TREE_CODE (arg0) == STRING_CST
  837.         && TREE_CODE (arg1) == INTEGER_CST
  838.         && !TREE_INT_CST_HIGH (arg1)
  839.         && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0))
  840.       {
  841.         if (TREE_TYPE (TREE_TYPE (arg0)) == integer_type_node)
  842.           {
  843.         exp = build_int_2 (((int *)TREE_STRING_POINTER (arg0))[i], 0);
  844.         TREE_TYPE (exp) = integer_type_node;
  845.         return expand_expr (exp, target, tmode, modifier);
  846.           }
  847.         if (TREE_TYPE (TREE_TYPE (arg0)) == char_type_node)
  848.           {
  849.         exp = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
  850.         TREE_TYPE (exp) = integer_type_node;
  851.         return expand_expr (convert (TREE_TYPE (TREE_TYPE (arg0)), exp), target, tmode, modifier);
  852.           }
  853.       }
  854.       }
  855.  
  856.       /* If this is a constant index into a constant array,
  857.      just get the value from the array.  */
  858.       if (TREE_READONLY (TREE_OPERAND (exp, 0))
  859.       && ! TREE_VOLATILE (TREE_OPERAND (exp, 0))
  860.       && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == ARRAY_TYPE
  861.       && TREE_LITERAL (TREE_OPERAND (exp, 1))
  862.       && TREE_CODE (TREE_OPERAND (exp, 0)) == VAR_DECL
  863.       && DECL_INITIAL (TREE_OPERAND (exp, 0))
  864.       && TREE_CODE (DECL_INITIAL (TREE_OPERAND (exp, 0))) != ERROR_MARK)
  865.     {
  866.       tree index = fold (TREE_OPERAND (exp, 1));
  867.       if (TREE_CODE (index) == INTEGER_CST)
  868.         {
  869.           int i = TREE_INT_CST_LOW (index);
  870.           tree init = CONSTRUCTOR_ELTS (DECL_INITIAL (TREE_OPERAND (exp, 0)));
  871.  
  872.           while (init && i--)
  873.         init = TREE_CHAIN (init);
  874.           if (init)
  875.         return expand_expr (fold (TREE_VALUE (init)), target, tmode, modifier);
  876.         }
  877.     }
  878.       /* Treat array-ref with constant index as a component-ref.  */
  879.  
  880.     case COMPONENT_REF:
  881.       {
  882.     register enum machine_mode mode1;
  883.     int volstruct = 0;
  884.     int bitsize;
  885.     tree tem = exp;
  886.     int bitpos = 0;
  887.     int unsignedp;
  888.  
  889.     if (TREE_CODE (exp) == COMPONENT_REF)
  890.       {
  891.         tree field = TREE_OPERAND (exp, 1);
  892.         bitsize = TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field);
  893.         mode1 = DECL_MODE (TREE_OPERAND (exp, 1));
  894.         unsignedp = TREE_UNSIGNED (field);
  895.       }
  896.     else
  897.       {
  898.         mode1 = TYPE_MODE (TREE_TYPE (exp));
  899.         bitsize = GET_MODE_BITSIZE (mode1);
  900.         unsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
  901.       }
  902.  
  903.     /* Compute cumulative bit-offset for nested component-refs
  904.        and array-refs, and find the ultimate containing object.  */
  905.  
  906.     while (1)
  907.       {
  908.         if (TREE_CODE (tem) == COMPONENT_REF)
  909.           {
  910.         bitpos += DECL_OFFSET (TREE_OPERAND (tem, 1));
  911.         if (TREE_THIS_VOLATILE (tem))
  912.           volstruct = 1;
  913.           }
  914.         else if (TREE_CODE (tem) == ARRAY_REF
  915.              && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
  916.              && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) == INTEGER_CST)
  917.           {
  918.         bitpos += (TREE_INT_CST_LOW (TREE_OPERAND (tem, 1))
  919.                * TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)))
  920.                * TYPE_SIZE_UNIT (TREE_TYPE (tem)));
  921.           }
  922.         else
  923.           break;
  924.         tem = TREE_OPERAND (tem, 0);
  925.       }
  926.  
  927.     op0 = expand_expr (tem, 0, VOIDmode,
  928.                (modifier == EXPAND_CONST_ADDRESS
  929.                 ? modifier : EXPAND_NORMAL));
  930.  
  931.     if (mode1 == BImode || GET_CODE (op0) == REG
  932.         || GET_CODE (op0) == SUBREG)
  933.       return extract_bit_field (op0, bitsize, bitpos, unsignedp,
  934.                     target, mode, tmode,
  935.                     TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT);
  936.     /* Get a reference to just this component.  */
  937.     if (modifier == EXPAND_CONST_ADDRESS)
  938.       op0 = gen_rtx (MEM, mode1, plus_constant (XEXP (op0, 0),
  939.                             (bitpos / BITS_PER_UNIT)));
  940.     else
  941.       op0 = change_address (op0, mode1,
  942.                 plus_constant (XEXP (op0, 0),
  943.                            (bitpos / BITS_PER_UNIT)));
  944.     MEM_IN_STRUCT_P (op0) = 1;
  945.     MEM_VOLATILE_P (op0) |= volstruct;
  946.     /* If OP0 is in the shared structure-value stack slot,
  947.        and it is not BLKmode, copy it into a register.
  948.        The shared slot may be clobbered at any time by another call.
  949.        BLKmode is safe because our caller will either copy the value away
  950.        or take another component and come back here.  */
  951.     if (mode != BLKmode
  952.         && TREE_CODE (TREE_OPERAND (exp, 0)) == CALL_EXPR
  953.         && TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == BLKmode)
  954.       op0 = copy_to_reg (op0);
  955.     if (mode == mode1 || mode1 == BLKmode || mode1 == tmode)
  956.       return op0;
  957.     if (target == 0)
  958.       target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
  959.     convert_move (target, op0, unsignedd_calls (exp);
  960.       if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
  961.       && GET_MODE_BITSIZE (TYPE_MODE (type)) <= HOST_BITS_PER_INT)
  962.     {
  963.       int negated;
  964.       if (modifier == EXPAND_SUM)
  965.         {
  966.           negate_1 = -1;
  967.           goto plus_minus;
  968.         }
  969.       subtarget = validate_subtarget (subtarget, TREE_OPERAND (exp, 1));
  970.       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
  971.       negated = - TREE_INT_CST_LOW (TREE_OPERAND (exp, 1));
  972.       if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_INT)
  973.         negated &= (1 << GET_MODE_BITSIZE (mode)) - 1;
  974.       op1 = gen_rtx (CONST_INT, VOIDmode, negated);
  975.       this_optab = add_optab;
  976.       goto binop2;
  977.     }
  978.       this_optab = sub_optab;
  979.       goto binop;
  980.  
  981.     case MULT_EXPR:
  982.       preexpand_calls (exp);
  983.       /* If first operand is constant, swap them.
  984.      Thus the following special case checks need only
  985.      check the second operand.  */
  986.       if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
  987.     {
  988.       register tree t1 = TREE_OPERAND (exp, 0);
  989.       TREE_OPERAND (exp, 0) = TREE_OPERAND (exp, 1);
  990.       TREE_OPERAND (exp, 1) = t1;
  991.     }
  992.  
  993.       /* Attempt to return something suitable for generating an
  994.      indexed address, for machines that support that.  */
  995.  
  996.       if (modifier == EXPAND_SUM
  997.       && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
  998.     {
  999.       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM);
  1000.  
  1001.       /* Apply distributive law if OP0 is x+c.  */
  1002.       if (GET_CODE (op0) == PLUS
  1003.           && GET_CODE (XEXP (op0, 1)) == CONST_INT)
  1004.         return gen_rtx (PLUS, mode,
  1005.                 gen_rtx (MULT, mode, XEXP (op0, 0),
  1006.                      gen_rtx (CONST_INT, VOIDmode,
  1007.                           TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))),
  1008.                 gen_rtx (CONST_INT, VOIDmode,
  1009.                      (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))
  1010.                       * INTVAL (XEXP (op0, 1)))));
  1011.  
  1012.       if (GET_CODE (op0) != REG)
  1013.         op0 = force_operand (op0, 0);
  1014.       if (GET_CODE (op0) != REG)
  1015.         op0 = copy_to_mode_reg (mode, op0);
  1016.  
  1017.       return gen_rtx (MULT, mode, op0,
  1018.               gen_rtx (CONST_INT, VOIDmode,
  1019.                    TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))));
  1020.     }
  1021.       subtarget = validate_subtarget (subtarget, TREE_OPERAND (exp, 1));
  1022.       /* Check for multiplying things that have been extended
  1023.      from a narrower type.  If this machine supports multiplying
  1024.      in that narrower type with a result in the desired type,
  1025.      do it that way, and avoid the explicit type-conversion.  */
  1026.       if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR
  1027.       && TREE_CODE (TREE_TYPE (exp)) == INTEGER_TYPE
  1028.       && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
  1029.           < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))
  1030.       && ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
  1031.            && int_fits_type_p (TREE_OPERAND (exp, 1),
  1032.                    TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
  1033.            /* Don't use a widening multiply if a shift will do.  */
  1034.            && exact_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))) < 0)
  1035.           ||
  1036.           (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
  1037.            && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
  1038.            ==
  1039.            TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))
  1040.            /* If both operands are extended, they must either both
  1041.           be zero-extended or both be sign-extended.  */
  1042.            && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
  1043.            ==
  1044.            TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))))))
  1045.     {
  1046.       enum machine_mode innermode
  1047.         = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)));
  1048.       this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
  1049.             ? umul_widen_optab : smul_widen_optab);
  1050.       if (mode == GET_MODE_WIDER_MODE (innermode)
  1051.           && this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
  1052.         {
  1053.           op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
  1054.                  0, VOIDmode, 0);
  1055.           if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
  1056.         op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
  1057.           else
  1058.         op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
  1059.                    0, VOIDmode, 0);
  1060.           EXPAND_SUM)
  1061.     return XEXP (op0, 0);
  1062.       op0 = force_operand (XEXP (op0, 0), target);
  1063.       if (flag_force_addr && GET_CODE (op0) != REG)
  1064.     return force_reg (Pmode, op0);
  1065.       return op0;
  1066.  
  1067.     case ENTRY_VALUE_EXPR:
  1068.       abort ();
  1069.  
  1070.     case ERROR_MARK:
  1071.       return const0_rtx;
  1072.  
  1073.     default:
  1074.       abort ();
  1075.     }
  1076.  
  1077.   /* Here to do an ordinary binary operator, generating an instruction
  1078.      from the optab already placed in `this_optab'.  */
  1079.  binop:
  1080.   /* Detect things like x = y | (a == b)
  1081.      and do them as (x = y), (a == b ? x |= 1 : 0), x.  */
  1082.   /* First, get the comparison or conditional into the second arg.  */
  1083.   if (comparison_code[(int) TREE_CODE (TREE_OPERAND (exp, 0))]
  1084.       || (TREE_CODE (TREE_OPERAND (exp, 0)) == COND_EXPR
  1085.       && (integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
  1086.           || integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 2)))))
  1087.     {
  1088.       if (this_optab == ior_optab || this_optab == add_optab
  1089.       || this_optab == xor_optab)
  1090.     {
  1091.       tree exch = TREE_OPERAND (exp, 1);
  1092.       TREE_OPERAND (exp, 1) = TREE_OPERAND (exp, 0);
  1093.       TREE_OPERAND (exp, 0) = exch;
  1094.     }
  1095.     }
  1096.   /* Optimize X + (Y ? Z : 0) by computing X and maybe adding Z.  */
  1097.   if (comparison_code[(int) TREE_CODE (TREE_OPERAND (exp, 1))]
  1098.       || (TREE_CODE (TREE_OPERAND (exp, 1)) == COND_EXPR
  1099.       && (integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 1), 1))
  1100.           || integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 1), 2)))))
  1101.     {
  1102.       if (this_optab == ior_optab || this_optab == add_optab
  1103.       || this_optab == xor_optab || this_optab == sub_optab
  1104.       || this_optab == lshl_optab || this_optab == ashl_optab
  1105.       || this_optab == lshr_optab || this_optab == ashr_optab
  1106.       || this_optab == rotl_optab || this_optab == rotr_optab)
  1107.     {
  1108.       tree thenexp;
  1109.       rtx thenv = 0;
  1110.  
  1111.       /* TARGET gets a reg in which we can perform the computation.
  1112.          Use the specified target if it's a pseudo reg and safe.  */
  1113.       target = validate_subtarget (subtarget, TREE_OPERAND (exp, 1));
  1114.       if (target == 0) target = gen_reg_rtx (mode);
  1115.  
  1116.       /* Compute X into the target.  */
  1117.       store_expr (TREE_OPERAND (exp, 0), target, 0);
  1118.       op0 = gen_label_rtx ();
  1119.  
  1120.       /* If other operand is a comparison COMP, treat it as COMP ? 1 : 0 */
  1121.       if (TREE_CODE (TREE_OPERAND (exp, 1)) != COND_EXPR)
  1122.         {
  1123.           do_jump (TREE_OPERAND (exp, 1), op0, 0);
  1124.           thenv = const1_rtx;
  1125.         }
  1126.       else if (integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 1), 2)))
  1127.         {
  1128.           do_jump (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), op0, 0);
  1129.           thenexp = TREE_OPERAND (TREE_OPERAND (exp, 1), 1);
  1130.         }
  1131.       else
  1132.         {
  1133.           do_jump (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0, op0);
  1134.           thenexp = TREE_OPERAND (TREE_OPERAND (exp, 1), 2);
  1135.         }
  1136.  
  1137.       if (thenv == 0)
  1138.         thenv = expand_expr (thenexp, 0, VOIDmode, 0);
  1139.  
  1140.       /* THENV is now Z, the value to operate on, as an rtx.
  1141.          We have already tested that Y isn't zero, so do the operation.  */
  1142.  
  1143.       if (this_optab == rotl_optab || this_optab == rotr_optab)
  1144.         temp = expand_binop (mode, this_optab, target, thenv, target,
  1145.                  -1, OPTAB_LIB);
  1146.       else if (this_optab == lshl_optab || this_optab == lshr_optab)
  1147.         temp = expand_binop (mode, this_optab, target, thenv, target,
  1148.                  1, OPTAB_LIB_WIDEN);
  1149.       else
  1150.         temp = expand_binop (mode, this_optab, target, thenv, target,
  1151.                  0, OPTAB_LIB_WIDEN);
  1152.       if (target != temp)
  1153.         emit_move_insn (target, temp);
  1154.  
  1155.       emit_queue ();
  1156.       do_pending_stack_adjust ();
  1157.       emit_label (op0);
  1158.       return target;
  1159.     }
  1160.     }
  1161.   subtarget = validate_subtarget (subtarget, TREE_OPERAND (exp, 1));
  1162.   op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
  1163.   op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
  1164.  binop2:
  1165.   temp = expand_binop (mode, this_optab, op0, op1, target,
  1166.                TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
  1167.   if (temp == 0)
  1168.     abort ();
  1169.   return temp;
  1170. }
  1171. #ifdef MPW
  1172. /* Ugliness to compensate for Mac ugliness.  The segment pragma has to be
  1173.    in an include file so non-ANSI compilers don't get perturbed. */
  1174. #include "seghack.h"
  1175. #endif /* MPW */
  1176.  
  1177. /* Expand an expression EXP that calls a built-in functi, STACK_BYTES);
  1178. #endif
  1179.  
  1180. #ifdef STACK_GROWS_DOWNWARD
  1181.       anti_adjust_stack (round_push (op0));
  1182. #endif
  1183.       /* Return a copy of current stack ptr, in TARGET if possible.  */
  1184.       if (target)
  1185.     emit_move_insn (target, stack_pointer_rtx);
  1186.       else
  1187.     target = copy_to_reg (stack_pointer_rtx);
  1188. #ifdef STACK_POINTER_OFFSET
  1189.       /* If the contents of the stack pointer reg are offset from the
  1190.      actual top-of-stack address, add the offset here.  */
  1191.       if (GET_CODE (target) == REG)
  1192.     emit_insn (gen_add2_insn (target,
  1193.                   gen_rtx (CONST_INT, VOIDmode,
  1194.                        (STACK_POINTER_OFFSET + STACK_BYTES - 1) / STACK_BYTES * STACK_BYTES)));
  1195.       else
  1196.     {
  1197.       rtx temp =
  1198.         expand_binop (GET_MODE (target), add_optab, target,
  1199.               gen_rtx (CONST_INT, VOIDmode,
  1200.                    (STACK_POINTER_OFFSET + STACK_BYTES - 1) / STACK_BYTES * STACK_BYTES),
  1201.               target,
  1202.               1, OPTAB_DIRECT);
  1203.       if (temp == 0) abort ();
  1204.       if (temp != target)
  1205.         emit_move_insn (target, temp);
  1206.     }
  1207. #endif
  1208. #ifndef STACK_GROWS_DOWNWARD
  1209.       anti_adjust_stack (round_push (op0));
  1210. #endif
  1211.       /* Some systems require a particular insn to refer to the stack
  1212.      to make the pages exist.  */
  1213. #ifdef HAVE_probe
  1214.       if (HAVE_probe)
  1215.     emit_insn (gen_probe ());
  1216. #endif
  1217.       return target;
  1218.  
  1219.     case BUILT_IN_FFS:
  1220.       if (arglist == 0
  1221.       /* Arg could be non-integer if user redeclared this fcn wrong.  */
  1222.       || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
  1223.     return const0_rtx;
  1224.  
  1225.       /* Compute the argument.  */
  1226.       op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
  1227.       /* Compute ffs, into TARGET if possible.
  1228.      Set TARGET to wherever the result comes back.  */
  1229.       target = expand_unop (mode, ffs_optab, op0, target, 1);
  1230.       if (target == 0)
  1231.     abort ();
  1232.       return target;
  1233.  
  1234. #ifdef APPLE_HAX
  1235. #ifdef ADDITIONAL_EXPAND_BUILTIN
  1236.       ADDITIONAL_EXPAND_BUILTIN
  1237. #endif
  1238. #endif /* APPLE_HAX */
  1239.  
  1240.     default:
  1241.       abort ();
  1242.     }
  1243. }
  1244.  
  1245. /* Expand code for a post- or pre- increment or decrement
  1246.    and return the RTX for the result.
  1247.    POST is 1 for postinc/decrements and 0 for preinc/decrements.  */
  1248.  
  1249. static rtx
  1250. expand_increment (exp, post)
  1251.      register tree exp;
  1252.      int post;
  1253. {
  1254.   register rtx op0, op1;
  1255.   register rtx temp;
  1256.   register tree incremented = TREE_OPERAND (exp, 0);
  1257.   optab this_optab = add_optab;
  1258.   int icode;
  1259.   enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
  1260.   int op0_is_copy = 0;
  1261.  
  1262.   /* Stabilize any component ref that might need to be
  1263.      evaluated more than once below.  */
  1264.   if (TREE_CODE (incremented) == COMPONENT_REF
  1265.       && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
  1266.       || DECL_MODE (TREE_OPERAND (incremented, 1)) == BImode))
  1267.     incremented = stabilize_reference (incremented);
  1268.  
  1269.   /* Compute the operands as RTX.
  1270.      Note whether OP0 is the actual lvalue or a copy of it:
  1271.      I believe it is a copy iff it is a register and insns were
  1272.      generated in computing it.  */
  1273.   temp = get_last_insn ();
  1274.   op0 = expand_expr (incremented, 0, VOIDmode, 0);
  1275.   if (temp != get_last_insn ())
  1276.     op0_is_copy = (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG);
  1277.   op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
  1278.  
  1279.   /* Decide whether incrementing or decrementing.  */
  1280.   if (TREE_CODE (exp) == POSTDECREMENT_EXPR
  1281.       || TREE_CODE (exp) == PREDECREMENT_EXPR)
  1282.     this_optab = sub_optab;
  1283.  
  1284.   /* If OP0 is not the actual lvalue, but rather a copy in a register,
  1285.      then we cannot just increment OP0.  We must
  1286.      therefore contrive to increment the original value.
  1287.      Then we can return OP0 since it is a copy of the old value.  */
  1288.   if (op0_is_copy)
  1289.     {
  1290.       /* This is the easiest way to increment the value wherever it is.
  1291.      Problems with multiple evaluation of INCREMENTED
  1292.      are prevented because either (1) it is a component_ref,
  1293.      in which case it was stabilized above, or (2) it is an array_ref
  1294.      with constant index in an array in a register, which is
  1295.      safe to reevaluate.  */
  1296.       tree newexp = build ((this_optab == add_optab
  1297.                 ? PLUS_EXPR : MINUS_EXPR),
  1298.                TREE_TYPE (exp),
  1299.                incremented,
  1300.                TREE_OPERAND (exp, 1));
  1301.        || DECL_PARAM(fndecl)->funcreturn == noreg)
  1302.     {
  1303.       if (is_pascal)
  1304.         {
  1305.           int adjsize;
  1306.  
  1307.           if (valreg)
  1308.             /* Get the value at sp and put into the result register. */
  1309.         emit_move_insn(valreg,
  1310.                    gen_rtx(MEM, GET_MODE (valreg), stack_pointer_rtx));
  1311.           /* Whether or not the result was put anywhere, the stack still
  1312.              needs to be adjusted to account for the result space alloc. */
  1313.           adjsize = GET_MODE_SIZE (return_mode);
  1314. #ifdef PUSH_ROUNDING
  1315.           adjsize = PUSH_ROUNDING (adjsize);
  1316. #endif
  1317.           if (flag_defer_pop && inhibit_defer_pop == 0)
  1318.         pending_stack_adjust += adjsize;
  1319.           else
  1320.         adjust_stack (gen_rtx (CONST_INT, VOIDmode, adjsize));
  1321.           /* Pascal routines pop args themselves, and we just popped any
  1322.          return stuff, so nothing is left now */
  1323.           stack_size = 0;
  1324.         }
  1325.       }
  1326. #endif /* APPLE_C */
  1327.  
  1328.   /* If returning from the subroutine does not automatically pop the args,
  1329.      we need an instruction to pop them sooner or later.
  1330.      Perhaps do it now; perhaps just record how much space to pop later.  */
  1331.  
  1332.   if (! RETURN_POPS_ARGS (TREE_TYPE (funtype))
  1333.       && stack_size != 0)
  1334.     {
  1335.       if (flag_defer_pop && inhibit_defer_pop == 0)
  1336.     pending_stack_adjust += stack_size;
  1337.       else
  1338.     adjust_stack (stack_size_rtx);
  1339.     }
  1340. }
  1341.  
  1342. /* At the start of a function, record that we have no previously-pushed
  1343.    arguments waiting to be popped.  */
  1344.  
  1345. void
  1346. init_pending_stack_adjust ()
  1347. {
  1348.   pending_stack_adjust = 0;
  1349. }
  1350.  
  1351. /* When exiting from function, if safe, clear out any pending stack adjust
  1352.    so the adjustment won't get done.  */
  1353.  
  1354. void
  1355. clear_pending_stack_adjust ()
  1356. {
  1357. #ifdef EXIT_IGNORE_STACK
  1358.   if (!flag_omit_frame_pointer && EXIT_IGNORE_STACK
  1359.       && ! TREE_INLINE (current_function_decl)
  1360.       && ! flag_inline_functions)
  1361.     pending_stack_adjust = 0;
  1362. #endif
  1363. }
  1364.  
  1365. /* Pop any previously-pushed arguments that have not been popped yet.  */
  1366.  
  1367. void
  1368. do_pending_stack_adjust ()
  1369. {
  1370.   if (inhibit_defer_pop == 0)
  1371.     {
  1372.       if (pending_stack_adjust != 0)
  1373.     adjust_stack (gen_rtx (CONST_INT, VOIDmode, pending_stack_adjust));
  1374.       pending_stack_adjust = 0;
  1375.     }
  1376. }
  1377.  
  1378. /* Data structure and subroutines used within expand_call.  */
  1379.  
  1380. struct arg_data
  1381. {
  1382.   /* Tree node for this argument.  */
  1383.   tree tree_value;
  1384.   /* Precomputed RTL value, or 0 if it isn't precomputed.  */
  1385.   rtx value;
  1386.   /* Register to pass this argument in, or 0 if passed on stack.  */
  1387.   rtx reg;
  1388.   /* Number of registers to use.  0 means put the whole arg in registers.
  1389.      Also 0 if not passed in registers.  */
  1390.   int partial;
  1391.   /* Offset of this argument from beginning of stack-args.  */
  1392.   struct args_size offset;
  1393.   /* Size of this argument on the stack, rounded up for any padding it gets,
  1394.      parts of the argument passed in registers do not count.
  1395.      If the FIRST_PARM_CALLER_OFFSET is negative, then register parms
  1396.      are counted here as well.  */
  1397.   struct args_size size;
  1398.   /* Nonzero if this arg has already been stored.  */
  1399.   int stored;
  1400.   /* const0_rtx means should preallocate stack space for this arg.
  1401.      Other non0 value is the stack slot, preallocated.
  1402.      Used only for BLKmode.  */
  1403.   rtx stack;
  1404. };
  1405.  
  1406. static void store_one_arg ();
  1407. static rtx target_for_arg ();
  1408.  
  1409. /* Generate all the code for a function call
  1410.    and return an rtx for its value.
  1411.    Store the value in TARGET (specified as an rtx) if convenient.
  1412.    If the value is stored in TARGET then TARGET is returned.
  1413.    If IGNORE is nonzero, then we ignore the value of the function call.  */
  1414.  
  1415. static rtx
  1416. expand_call (exp, target, ignore)
  1417.      tree exp;
  1418.      rtx target;
  1419.      int ignore;
  1420. {
  1421.   /* List of actual parameters.  */
  1422.   tree actparms = TREE_OPERAND (exp, 1);
  1423.   /* RTX for the function to be called.  */
  1424.   rtx funexp;
  1425.   /* Data type of the function.  */
  1426.   tree funtype;
  1427.   /* Declaration of the function being called,
  1428.      or 0 if the function is computed (not known by name).  */
  1429.   tree fndecl = 0;
  1430.  
  1431.   /* Register in which non-BLKmode value will be returned,
  1432.      or 0 if no value or if value is BLKmode.  */
  1433.   rtx valreg;
  1434.   /* Address where we should return a BLKmode value;
  1435.      0 if value not BLKmode.  */
  1436.   rtx structure_value_addr = 0;
  1437.   /* Nonzero if that address is being passed by treating it as
  1438.      an extra, implicit first parameter.  Otherwise,
  1439.      it is passed by being copied directly into struct_value_rtx.  */
  1440.   int structure_value_addr_parm = 0;
  1441.   /* Nonzero if called function returns an aggregate in memory PCC style,
  1442.      by returning the address of where to find it.  */
  1443.   int pcc_struct_value = 0;
  1444.  
  1445.   /* Number of actual parameters in this call, including struct value addr.  */
  1446.   int num_actuals;
  1447.   /* Number of named args.  Args after this are anonymous ones
  1448.      and they must all go on the stack.  */
  1449.   int n_named_args;
  1450.  
  1451.   /* Vector of information about each argument.
  1452.      Arguments are numbered in the order they will be pushed,
  1453.      not the order they are written.  */
  1454.   struct arg_data *args;
  1455.  
  1456.   /* Total size in bytes of all the stack-parms scanned so far.  */
  1457.   struct args_size args_size;
  1458.   /* Remember initial value of args_size.constant.  */
  1459.   int starting_args_size;
  1460.   /* Nonzero means count reg-parms' size in ARGS_SIZE.  */
  1461.   int stack_count_regparms = 0;
  1462.   /* Data on reg parms scanned so far.  */
  1463.   CUMULATIVE_ARGS args_so_far;
  1464.   /* Nonzero if a reg parm has been scanned.  */
  1465.   int reg_parm_seen;
  1466.   /* Nonzero if we must avoid push-insns in the args for this call.  */
  1467.   int must_preallocate;
  1468.   /* 1 if scanning parms front to back, -1 if scanning back to front.  */
  1469.   int inc;
  1470.   /* Address of space preallocated for stack parms
  1471.      (on machines that lack push insns), or 0 if space not preallocated.  */
  1472.   rtx argblock = 0;
  1473.  
  1474.   /* Nonzero if it is plausible that this is a call to alloca.  */
  1475.   int may_be_alloca;
  1476.   /* Nonzero if this is a call to setjmp or a related function.  */
  1477.   int is_setjmp;
  1478.   /* Nonzero if this is a call to an inline function.  */
  1479.   int is_integrable = 0;
  1480. #ifdef APPLE_C
  1481.   /* Nonzero if this is a call to a pascal function. */
  1482.   int is_pascal = 0;
  1483.   enum machine_mode pascal_return_mode = VOIDmode;
  1484. #endif /* APPLE_C */
  1485.   /* Nonzero if this is a call to __builtin_new.  */
  1486.   int is_builtin_new;
  1487.   /* Nonzero if this is a call to a `const' function.  */
  1488.   int is_const = 0;
  1489.  
  1490.   /* Nonzero if there are BLKmode args whose data types require them
  1491.      to be passed in memory, not (even partially) in registers.  */
  1492.   int BLKmode_parms_forced = 0;
  1493.   /* The offset of the first BLKmode parameter which 
  1494.      *must* be passed in memory.  */
  1495.   int BLKmode_parms_first_offset = 0;
  1496.   /* Total size of BLKmode parms which could usefully be preallocated.  */
  1497.   int BLKmode_parms_sizes = 0;
  1498.  
  1499.   /* Amount stack was adjusted to protect BLKmode parameters
  1500.      which are below the nominal "stack address" value.  */
  1501.   rtx protected_stack = 0;
  1502.  
  1503.   /* The last insn before the things that are intrinsically part of the call.
  1504.      The beginning reg-note goes on the insn after this one.  */
  1505.   rtx insn_before;
  1506.  
  1507.   rtx old_stack_level = 0;
  1508.   int old_pending_adj;
  1509.   int old_inhibit_defer_pop = inhibit_defer_pop;
  1510.   tree old_cleanups = cleanups_of_this_call;
  1511.   rtx use_insns;
  1512.  
  1513.   register tree p;
  1514.   register int i;
  1515.  
  1516.   /* See if we can find a DECL-node for the actual function.
  1517.      As a result, decide whether this is a call to an integrable function.  */
  1518.  
  1519.   p = TREE_OPERAND (exp, 0);
  1520.   if (TREE_CODE (p) == ADDR_EXPR)
  1521.     {
  1522.       fndecl = TREE_OPERAND (p, 0);
  1523.       if (TREE_CODE (fndecl) != FUNCTION_DECL)
  1524.     fndecl = 0;
  1525.       else
  1526.     {
  1527.       extern tree current_function_decl;
  1528.  
  1529.       if (fndecl != current_function_decl
  1530.           && DECL_SAVED_INSNS (fndecl))
  1531.         is_integrable = 1;
  1532.       else
  1533.         {
  1534.           /* In case this function later becomes inlineable,
  1535.          record that there was already a non-inline call to it.  */
  1536.           mark_addressable (fndecl);
  1537.         }
  1538.  
  1539.       if (TREE_READONLY (fndecl) && ! TREE_THIS_VOLATILE (fndecl))
  1540.         is_const = 1;
  1541. #ifdef APPLE_C
  1542.       if (TREE_PASCAL (fndecl))
  1543.         is_pascal = 1;
  1544. #endif /* APPLE_C */
  1545.     }
  1546.     }
  1547.  
  1548.   /* When calling a const function, we must pop the stack args right away,
  1549.      so that the pop is deleted or moved with the call.  */
  1550.   if (is_const)
  1551.     NO_DEFER_POP;
  1552.  
  1553.   /* Set up a place to return a structure.  */
  1554.  
  1555.   /* Cater to broken compilers.  */
  1556.   if (aggregate_value_p (exp))
  1557.     {
  1558.       /* This call returns a big structure.  */
  1559. #ifdef PCC_STATIC_STRUCT_RETURN
  1560.       if (flag_pcc_struct_return)
  1561.     {
  1562.       pcc_struct_value = 1;
  1563.       is_integrable = 0;  /* Easier than making that case work right.  */
  1564.     }
  1565.       else
  1566. #endif
  1567.     {
  1568.       if (target && GET_CODE (target) == MEM)
  1569.         {
  1570.           structure_value_addr = XEXP (target, 0);
  1571.           if (reg_mentioned_p (stack_pointer_rtx, structure_value_addr))
  1572.         structure_value_addr = copy_to_reg (structure_value_addr);
  1573.         }
  1574.       else
  1575.         {
  1576.           /* Make room on the stack to hold the value.  */
  1577.           structure_value_addr
  1578.         = get_structure_value_addr (expr_size (exp));
  1579.           target = 0;
  1580.         }
  1581.     }
  1582.     }
  1583.  
  1584.   /* If called function is inline, try to integrate it.  */
  1585.  
  1586.   if (is_integrable)
  1587.     {
  1588.       extern rtx expand_inline_function ();
  1589.       rtx temp;
  1590.  
  1591.       temp = expand_inline_function (fndecl, actparms, target,
  1592.                      ignore, TREE_TYPE (exp),
  1593.                      structure_value_addr);
  1594.  
  1595.       /* If inlining succeeded, return.  */
  1596.       if ((int) temp != -1)
  1597.     return temp;
  1598.  
  1599.       /* If inlining failed, mark FNDECL as needing to be compiled
  1600.      separately after all.  */
  1601.       TREE_ADDRESSABLE (fndecl) = 1;
  1602.       TREE_ADDRESSABLE (DECL_NAME (fndecl)) = 1;
  1603.     }
  1604.  
  1605. #if 0
  1606.   /* Unless it's a call to a specific function that isn't alloca,
  1607.      if it has one argument, we must assume it might be alloca.  */
  1608.  
  1609.   may_be_alloca =
  1610.     (!(fndecl != 0
  1611.        && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
  1612.           "alloca"))
  1613.      && actparms != 0
  1614.      && TREE_CHAIN (actparms) == 0);
  1615. #else
  1616.   /* We assume that alloca will always be called by name.  It
  1617.      makes no sense to pass it as a pointer-to-function to
  1618.      anything that does not understand its behavior.  */
  1619.   may_be_alloca =
  1620.     (fndecl && (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "alloca")
  1621.         || ! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
  1622.                  "__builtin_alloca")));
  1623. #endif
  1624.  
  1625.   /* See if this is a call to a function that can return more than once.  */
  1626.  
  1627.   is_setjmp
  1628.     = (fndecl != 0
  1629.        && (!strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "setjmp")
  1630.        || !strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "_setjmp")));
  1631.  
  1632.   is_builtin_new
  1633.     = (fndecl != 0
  1634.        && (!strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__builtin_new")));
  1635.  
  1636.   if (may_be_alloca)
  1637.     {
  1638.       frame_pointer_needed = 1;
  1639.       may_call_alloca = 1;
  1640.       current_function_calls_alloca = 1;
  1641.     }
  1642.  
  1643.   /* Don't let pending stack adjusts add up to too much.
  1644.      Also, do all pending adjustments now
  1645.      if there is any chance this might be a call to alloca.  */
  1646.  
  1647.   if (pending_stack_adjust >= 32
  1648.       || (pending_stack_adjust > 0 && may_be_alloca))
  1649.     do_pending_stack_adjust ();
  1650.  
  1651.   /* Operand 0 is a pointer-to-function; get the type of the function.  */
  1652.   funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
  1653.   if (TREE_CODE (funtype) != POINTER_TYPE)
  1654.     abort ();
  1655.   funtype = TREE_TYPE (funtype);
  1656.  
  1657. #ifdef APPLE_C
  1658.   if (TREE_PASCAL (funtype))
  1659.     is_pascal = 1;
  1660. #endif /* APPLE_C */
  1661.  
  1662.   /* If struct_value_rtx is 0, it means pass the address
  1663.      as if it were an extra parameter.  */
  1664.   if (structure_value_addr && struct_value_rtx == 0)
  1665.     {
  1666.       rtx tem;
  1667.  
  1668.       if( fndecl )
  1669.         INIT_CUMULATIVE_ARGS (args_so_far, funtype, DECL_PARAM(fndecl));
  1670.       else
  1671.     INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL);
  1672.       tem = FUNCTION_ARG (args_so_far, Pmode,
  1673.               build_pointer_type (TREE_TYPE (funtype)), 1);
  1674.       if (tem == 0)
  1675.     {
  1676.       actparms = tree_cons (error_mark_node,
  1677.                 build (SAVE_EXPR,
  1678.                        type_for_size (GET_MODE_BITSIZE (Pmode), 0),
  1679.                        0,
  1680.                        force_reg (Pmode, structure_value_addr)),
  1681.                 actparms);
  1682.       structure_value_addr_parm = 1;
  1683.     }
  1684.     }
  1685.  
  1686. #ifdef APPLE_C
  1687.   if (fndecl == NULL
  1688.       || DECL_PARAM(fndecl) == NULL
  1689.       || DECL_PARAM(fndecl)->funcreturn == noreg )
  1690.   if (is_pascal && TYPE_MODE (TREE_TYPE (exp)) != VOIDmode)
  1691.     {
  1692.       if (structure_value_addr && ! structure_value_addr_parm)
  1693.     {
  1694.       emit_move_insn (struct_value_rtx,
  1695.               force_reg (Pmode,
  1696.                      force_operand (structure_value_addr, 0)));
  1697.         }
  1698.       else
  1699.     {
  1700.       pascal_return_mode = TYPE_MODE (TREE_TYPE (exp));
  1701. #ifdef PUSH_ROUNDING
  1702.       push_block (gen_rtx (CONST_INT, VOIDmode,
  1703.                    PUSH_ROUNDING (GET_MODE_SIZE (pascal_return_mode))));
  1704. #else
  1705.       push_block (gen_rtx (CONST_INT, VOIDmode,
  1706.                    GET_MODE_SIZE (pascal_return_mode)));
  1707. #endif
  1708.         }
  1709.     }
  1710. #endif /* APPLE_C */
  1711.   /* Count the arguments and set NUM_ACTUALS.  */
  1712.   for (p = actparms, i = 0; p; p = TREE_CHAIN (p)) i++;
  1713.   num_actuals = i;
  1714.  
  1715.   /* Compute number of named args.
  1716.      Don't include the last named arg if anonymous args follow.
  1717.      (If no anonymous args follow, the result of list_length
  1718.      is actually one too large.)  */
  1719.   if (TYPE_ARG_TYPES (funtype) != 0)
  1720.     n_named_args = list_length (TYPE_ARG_TYPES (funtype)) - 1;
  1721.   else
  1722.     /* If we know nothing, treat all args as named.  */
  1723.     n_named_args = num_actuals;
  1724.  
  1725.   /* Make a vector to hold all the information about each arg.  */
  1726.   args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
  1727.   bzero (args, num_actuals * sizeof (struct arg_data));
  1728.  
  1729.   args_size.constant = 0;
  1730.   args_size.var = 0;
  1731. #ifdef FIRST_PARM_CALLER_OFFSET
  1732.   args_size.constant = FIRST_PARM_CALLER_OFFSET (funtype);
  1733.   stack_count_regparms = 1;
  1734. #endif
  1735.   starting_args_size = args_size.constant;
  1736.  
  1737.   /* In this loop, we consider args in the order they are written.
  1738.      We fill up ARGS from the front of from the back if necessary
  1739.      so that in any case the first arg to be pushed ends up at the front.  */
  1740.  
  1741. #ifdef APPLE_C
  1742.   push_args_reversed = (is_pascal ? 0 : 1);
  1743.  
  1744.   i = (push_args_reversed ? num_actuals - 1 : 0);
  1745.   inc = (push_args_reversed ? -1 : 1);
  1746. #else
  1747. #ifdef PUSH_ARGS_REVERSED
  1748.   i = num_actuals - 1, inc = -1;
  1749.   /* In this case, must reverse order of args
  1750.      so that we compute and push the last arg first.  */
  1751. #else
  1752.   i = 0, inc = 1;
  1753. #endif
  1754. #endif /* APPLE_C */
  1755.  
  1756.   if( fndecl )
  1757.     INIT_CUMULATIVE_ARGS (args_so_far, funtype, DECL_PARAM(fndecl));
  1758.   else
  1759.     INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL);
  1760.  
  1761.   for (p = actparms; p; p = TREE_CHAIN (p), i += inc)
  1762.     {
  1763.       tree type = TREE_TYPE (TREE_VALUE (p));
  1764.       args[i].tree_value = TREE_VALUE (p);
  1765.       args[i].offset = args_size;
  1766.  
  1767.       if (type == error_mark_node
  1768.       || TYPE_SIZE (type) == 0)
  1769.     continue;
  1770.  
  1771.       /* Decide where to pass this arg.  */
  1772.       /* args[i].reg is nonzero if all or part is passed in registers.
  1773.      args[i].partial is nonzero if part but not all is passed in registers,
  1774.       and the exact value says how many words are passed in registers.  */
  1775.  
  1776.       if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
  1777.       && args_size.var == 0
  1778.       /* error_mark_node here is a flag for the fake argument
  1779.          for a structure value address.  */
  1780.       && TREE_PURPOSE (p) != error_mark_node)
  1781.     {
  1782.       args[i].reg = FUNCTION_ARG (args_so_far, TYPE_MODE (type), type,
  1783.                       i < n_named_args);
  1784.       /* If this argument needs more than the usual parm alignment, do
  1785.          extrinsic padding to reach that alignment.  */
  1786.  
  1787. #ifdef MAX_PARM_BOUNDARY
  1788.       /* If MAX_PARM_BOUNDARY is not defined, it means that the usual
  1789.          alignment requirements are relaxed for parms, and that no parm
  1790.          needs more than PARM_BOUNDARY, regardless of data type.  */
  1791.  
  1792.       if (PARM_BOUNDARY < TYPE_ALIGN (type))
  1793.         {
  1794.           int boundary = PARM_BOUNDARY;
  1795.  
  1796.           /* Determine the boundary to pad up to.  */
  1797.           if (TYPE_ALIGN (type) > boundary)
  1798.         boundary = TYPE_ALIGN (type);
  1799.           if (boundary > MAX_PARM_BOUNDARY)
  1800.         boundary = MAX_PARM_BOUNDARY;
  1801.  
  1802.           /* If the previous args don't reach such a boundary,
  1803.          advance to the next one.  */
  1804.           boundary /= BITS_PER_UNIT;
  1805.           args[i].offset.constant += boundary - 1;
  1806.           args[i].offset.constant &= ~(boundary - 1);
  1807.           args_size.constant += boundary - 1;
  1808.           args_size.constant &= ~(boundary - 1);
  1809.  
  1810.           if (args_size.var != 0)
  1811.         abort ();        /* This case not implemented yet */
  1812.         }
  1813. #endif /* MAX_PARM_BOUNDARY */
  1814.  
  1815. #ifdef FUNCTION_ARG_PARTIAL_NREGS
  1816.       args[i].partial
  1817.         = FUNCTION_ARG_PARTIAL_NREGS (args_so_far,
  1818.                       TYPE_MODE (type), type,
  1819.                       i < n_named_args);
  1820. #endif
  1821.     }
  1822.  
  1823.       /* Compute the stack-size of this argument.  */
  1824.  
  1825.       if (args[i].reg != 0 && args[i].partial == 0
  1826.       && ! stack_count_regparms)
  1827.     /* On most machines, don't count stack space for a register arg.  */
  1828.     ;
  1829.       else if (TYPE_MODE (type) != BLKmode)
  1830.     {
  1831.       register int size;
  1832.  
  1833.       size = GET_MODE_SIZE (TYPE_MODE (type));
  1834.       /* Compute how much space the push instruction will push.
  1835.          On many machines, pushing a byte will advance the stack
  1836.          pointer by a halfword.  */
  1837. #ifdef PUSH_ROUNDING
  1838.       size = PUSH_ROUNDING (size);
  1839. #endif
  1840.       /* Compute how much space the argument should get:
  1841.          maybe pad to a multiple of the alignment for arguments.  */
  1842.       if (none == FUNCTION_ARG_PADDING (TYPE_MODE (type), const0_rtx))
  1843.         args[i].size.constant = size;
  1844.       else
  1845.         args[i].size.constant
  1846.           = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
  1847.           / (PARM_BOUNDARY / BITS_PER_UNIT))
  1848.          * (PARM_BOUNDARY / BITS_PER_UNIT));
  1849.     }
  1850.       else
  1851.     {
  1852.       register tree size = size_in_bytes (type);
  1853.  
  1854.       /* A nonscalar.  Round its size up to a multiple
  1855.          of PARM_BOUNDARY bits, unless it is not supposed to be padded.  */
  1856.       if (none
  1857.           != FUNCTION_ARG_PADDING (TYPE_MODE (type),
  1858.                        expand_expr (size, 0, VOIDmode, 0)))
  1859.         size = convert_units (convert_units (size, BITS_PER_UNIT,
  1860.                          PARM_BOUNDARY),
  1861.                   PARM_BOUNDARY, BITS_PER_UNIT);
  1862.       ADD_PARM_SIZE (args[i].size, size);
  1863.  
  1864.       /* Certain data types may not be passed in registers
  1865.          (eg C++ classes with constructors).
  1866.          Also, BLKmode parameters initialized from CALL_EXPRs
  1867.          are treated specially, if it is a win to do so.  */
  1868.       if (TREE_CODE (TREE_VALUE (p)) == CALL_EXPR
  1869.           || TREE_ADDRESSABLE (type))
  1870.         {
  1871.           if (TREE_ADDRESSABLE (type))
  1872.         BLKmode_parms_forced = 1;
  1873.           /* This is a marker for such a parameter.  */
  1874.           args[i].stack = const0_rtx;
  1875.           BLKmode_parms_sizes += TREE_INT_CST_LOW (size);
  1876.  
  1877.           /* If this parm's location is "below" the nominal stack pointer,
  1878.          note to decrement the stack pointer while it is computed.  */
  1879. #ifdef FIRST_PARM_CALLER_OFFSET
  1880.           if (BLKmode_parms_first_offset == 0)
  1881.         BLKmode_parms_first_offset
  1882.           /* If parameter's offset is variable, assume the worst.  */
  1883.           = (args[i].offset.var
  1884.              ? FIRST_PARM_CALLER_OFFSET (funtype)
  1885.              : args[i].offset.constant);
  1886. #endif
  1887.         }
  1888.     }
  1889.  
  1890.       /* If a part of the arg was put into registers,
  1891.      don't include that part in the amount pushed.  */
  1892.       if (! stack_count_regparms)
  1893.     args[i].size.constant
  1894.       -= ((args[i].partial * UNITS_PER_WORD)
  1895.           / (PARM_BOUNDARY / BITS_PER_UNIT)
  1896.           * (PARM_BOUNDARY / BITS_PER_UNIT));
  1897.  
  1898.       /* Update ARGS_SIZE, the total stack space for args so far.  */
  1899.  
  1900.       args_size.constant += args[i].size.constant;
  1901.       if (args[i].size.var)
  1902.     {
  1903.       ADD_PARM_SIZE (args_size, args[i].size.var);
  1904.     }
  1905.  
  1906.       /* Increment ARGS_SO_FAR, which has info about which arg-registers
  1907.      have been used, etc.  */
  1908.  
  1909.       FUNCTION_ARG_ADVANCE (args_so_far, TYPE_MODE (type), type,
  1910.                 i < n_named_args);
  1911.     }
  1912.  
  1913.   /* If we would have to push a partially-in-regs parm
  1914.      before other stack parms, preallocate stack space instead.  */
  1915.   must_preallocate = 0;
  1916.   {
  1917.     int partial_seen = 0;
  1918.     for (i = 0; i < num_actuals; i++)
  1919.       {
  1920.     if (args[i].partial > 0)
  1921.       partial_seen = 1;
  1922.     else if (partial_seen && args[i].reg == 0)
  1923.       must_preallocate = 1;
  1924.       }
  1925.   }
  1926.  
  1927.   /* Precompute all register parameters.  It isn't safe to compute anything
  1928.      once we have started filling any specific hard regs.
  1929.      If this function call is cse'able, precompute all the parameters.  */
  1930.  
  1931.   reg_parm_seen = 0;
  1932.   for (i = 0; i < num_actuals; i++)
  1933.     if (args[i].reg != 0 || is_const)
  1934.       {
  1935.     int j;
  1936.     int struct_value_lossage = 0;
  1937.  
  1938.     /* First, see if this is a precomputed struct-returning function call
  1939.        and other subsequent parms are also such.  */
  1940.     if ((TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
  1941.          || RETURN_IN_MEMORY (TREE_TYPE (args[i].tree_value)))
  1942.         && TREE_CODE (args[i].tree_value) == CALL_EXPR)
  1943.       for (j = i + 1; j < num_actuals; j++)
  1944.         if ((TYPE_MODE (TREE_TYPE (args[j].tree_value)) == BLKmode
  1945.          || RETURN_IN_MEMORY (TREE_TYPE (args[j].tree_value)))
  1946.         && TREE_CODE (args[j].tree_value) == CALL_EXPR
  1947.         && args[j].reg != 0 || is_const)
  1948.           {
  1949.         /* We have two precomputed structure-values call expressions
  1950.            in our parm list.  Both of them would normally use
  1951.            the structure-value block.  To avoid the conflict,
  1952.            compute this parm with a different temporary block.  */
  1953.         int size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
  1954.         rtx structval = assign_stack_local (BLKmode, size);
  1955.         args[i].value = expand_expr (args[i].tree_value, structval,
  1956.                          VOIDmode, 0);
  1957.         struct_value_lossage = 1;
  1958.         break;
  1959.           }
  1960.     if (!struct_value_lossage)
  1961.       args[i].value = expand_expr (args[i].tree_value, 0, VOIDmode, 0);
  1962.  
  1963.     if (args[i].reg != 0)
  1964.       reg_parm_seen = 1;
  1965.  
  1966.     if (GET_CODE (args[i].value) != MEM
  1967.         && ! CONSTANT_P (args[i].value)
  1968.         && GET_CODE (args[i].value) != CONST_DOUBLE)
  1969.       args[i].value
  1970.         = force_reg (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
  1971.              args[i].value);
  1972.     /* ANSI doesn't require a sequence point here,
  1973.        but PCC has one, so this will avoid some problems.  */
  1974.     emit_queue ();
  1975.       }
  1976.  
  1977.   /* Get the function to call, in the form of RTL, if it is a constant.  */
  1978.   if (fndecl && is_const)
  1979.     {
  1980.       /* Get a SYMBOL_REF rtx for the function address.  */
  1981.       funexp = XEXP (DECL_RTL (fndecl), 0);
  1982.  
  1983. #ifndef NO_FUNCTION_CSE
  1984.       /* Pass the address through a pseudoreg, if desired,
  1985.      before the "beginning" of the library call.
  1986.      So this insn isn't "part of" the library call, in case that
  1987.      is deleted, or cse'd.  */
  1988.       if (! flag_no_function_cse)
  1989.     funexp = copy_to_mode_reg (Pmode, funexp);
  1990. #endif
  1991.     }
  1992.  
  1993.   /* Now we are about to start emitting insns that can be deleted
  1994.      if the libcall is deleted.  */
  1995.   insn_before = get_last_insn ();
  1996.  
  1997.   /* Maybe do additional rounding on the size of the arguments.  */
  1998. #ifdef STACK_ARGS_ADJUST
  1999.   STACK_ARGS_ADJUST (args_size);
  2000. #endif
  2001.  
  2002.   /* If we have no actual push instructions, or shouldn't use them,
  2003.      or we need a variable amount of space, make space for all args right now.
  2004.      Round the needed size up to multiple of STACK_BOUNDARY.  */
  2005.  
  2006.   if (args_size.var != 0)
  2007.     {
  2008.       old_stack_level = copy_to_mode_reg (Pmode, stack_pointer_rtx);
  2009.       old_pending_adj = pending_stack_adjust;
  2010.       argblock = push_block (round_push (ARGS_SIZE_RTX (args_size)));
  2011.     }
  2012.   else if (args_size.constant > 0)
  2013.     {
  2014.       int needed = args_size.constant;
  2015.  
  2016. #ifdef STACK_BOUNDARY
  2017.       needed = (needed + STACK_BYTES - 1) / STACK_BYTES * STACK_BYTES;
  2018. #endif
  2019.       args_size.constant = needed;
  2020.  
  2021.       if (
  2022. #ifndef PUSH_ROUNDING
  2023.       1  /* Always preallocate if no push insns.  */
  2024. #else
  2025.       must_preallocate || BLKmode_parms_forced
  2026.       || BLKmode_parms_sizes > (args_size.constant >> 1)
  2027. #endif
  2028.       )
  2029.     {
  2030.       /* Try to reuse some or all of the pending_stack_adjust
  2031.          to get this space.  Maybe we can avoid any pushing.  */
  2032.       if (needed > pending_stack_adjust)
  2033.         {
  2034.           needed -= pending_stack_adjust;
  2035.           pending_stack_adjust = 0;
  2036.         }
  2037.       else
  2038.         {
  2039.           pending_stack_adjust -= needed;
  2040.           needed = 0;
  2041.         }
  2042.       argblock = push_block (gen_rtx (CONST_INT, VOIDmode, needed));
  2043.     }
  2044.     }
  2045. #ifndef PUSH_ROUNDING
  2046.   else if (BLKmode_parms_forced)
  2047.     {
  2048.       /* If we have reg-parms that need to be temporarily on the stack,
  2049.      set up an arg block address even though there is no space
  2050.      to be allocated for it.  */
  2051.       argblock = push_block (const0_rtx);
  2052.     }
  2053. #endif
  2054.  
  2055. #if 0
  2056.   /* If stack needs padding below the args, increase all arg offsets
  2057.      so the args are stored above the padding.  */
  2058.   if (stack_padding)
  2059.     for (i = 0; i < num_actuals; i++)
  2060.       args[i].offset.constant += stack_padding;
  2061. #endif
  2062.  
  2063.   /* Don't try to defer pops if preallocating, not even from the first arg,
  2064.      since ARGBLOCK probably refers to the SP.  */
  2065.   if (argblock)
  2066.     NO_DEFER_POP;
  2067.  
  2068. #ifdef STACK_GROWS_DOWNWARD
  2069.   /* If any BLKmode parms need to be preallocated in space
  2070.      below the nominal stack-pointer address, we need to adjust the
  2071.      stack pointer so that this location is temporarily above it.
  2072.      This ensures that computation won't clobber that space.  */
  2073.   if (BLKmode_parms_first_offset < 0 && argblock != 0)
  2074.     {
  2075.       int needed = -BLKmode_parms_first_offset;
  2076.       argblock = copy_to_reg (argblock);
  2077.  
  2078. #ifdef STACK_BOUNDARY
  2079.       needed = (needed + STACK_BYTES - 1) / STACK_BYTES * STACK_BYTES;
  2080. #endif
  2081.       protected_stack = gen_rtx (CONST_INT, VOIDmode, needed);
  2082.       anti_adjust_stack (protected_stack);
  2083.     }
  2084. #endif /* STACK_GROWS_DOWNWARD */
  2085.  
  2086.   /* Get the function to call, in the form of RTL.  */
  2087.   if (fndecl)
  2088.     /* Get a SYMBOL_REF rtx for the function address.  */
  2089.     funexp = XEXP (DECL_RTL (fndecl), 0);
  2090.   else
  2091.     /* Generate an rtx (probably a pseudo-register) for the address.  */
  2092.     {
  2093.       funexp = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
  2094.       emit_queue ();
  2095.     }
  2096.  
  2097.   /* Now compute and store all non-register parms.
  2098.      These come before register parms, since they can require block-moves,
  2099.      which could clobber the registers used for register parms.
  2100.      Parms which have partial registers are not stored here,
  2101.      but we do preallocate space here if they want that.  */
  2102.  
  2103.   for (i = 0; i < num_actuals; i++)
  2104.     {
  2105.       /* Preallocate the stack space for a parm if appropriate
  2106.      so it can be computed directly in the stack space.  */
  2107.       if (args[i].stack != 0 && argblock != 0)
  2108.     args[i].stack = target_for_arg (TREE_TYPE (args[i].tree_value),
  2109.                     ARGS_SIZE_RTX (args[i].size),
  2110.                     argblock, args[i].offset);
  2111.       else
  2112.     args[i].stack = 0;
  2113.  
  2114.       if (args[i].reg == 0
  2115.       && TYPE_SIZE (TREE_TYPE (args[i].tree_value)) != 0)
  2116.     store_one_arg (&args[i], argblock, may_be_alloca);
  2117.     }
  2118.  
  2119.   /* Now store any partially-in-registers parm.
  2120.      This is the last place a block-move can happen.  */
  2121.   if (reg_parm_seen)
  2122.     for (i = 0; i < num_actuals; i++)
  2123.       if (args[i].partial != 0)
  2124.     store_one_arg (&args[i], argblock, may_be_alloca);
  2125.  
  2126.   if (protected_stack != 0)
  2127.     adjust_stack (protected_stack);
  2128.  
  2129.   /* Pass the function the address in which to return a structure value.  */
  2130. #ifdef APPLE_C
  2131.   if (structure_value_addr && ! structure_value_addr_parm && ! is_pascal)
  2132. #else
  2133.   if (structure_value_addr && ! structure_value_addr_parm)
  2134. #endif /* APPLE_C */
  2135.     emit_move_insn (struct_value_rtx,
  2136.             force_reg (Pmode, force_operand (structure_value_addr, 0)));
  2137.  
  2138.   /* Now set up any wholly-register parms.  They were computed already.  */
  2139.   if (reg_parm_seen)
  2140.     for (i = 0; i < num_actuals; i++)
  2141.       if (args[i].reg != 0 && args[i].partial == 0)
  2142.     store_one_arg (&args[i], argblock, may_be_alloca);
  2143.  
  2144.   /* Perform postincrements before actually calling the function.  */
  2145.   emit_queue ();
  2146.  
  2147.   /* All arguments and registers used for the call must be set up by now!  */
  2148.  
  2149.   /* ??? Other languages need a nontrivial second argument (static chain).  */
  2150.   funexp = prepare_call_address (funexp, 0);
  2151.  
  2152.   /* Mark all register-parms as living through the call.  */
  2153.   start_sequence ();
  2154.   for (i = 0; i < num_actuals; i++)
  2155.     if (args[i].reg != 0)
  2156.       {
  2157.     if (args[i].partial > 0)
  2158.       use_regs (REGNO (args[i].reg), args[i].partial);
  2159.     else if (GET_MODE (args[i].reg) == BLKmode)
  2160.       use_regs (REGNO (args[i].reg),
  2161.             ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
  2162.               + UNITS_PER_WORD - 1)
  2163.              / UNITS_PER_WORD));
  2164.     else
  2165.       emit_insn (gen_rtx (USE, VOIDmode, args[i].reg));
  2166.       }
  2167.  
  2168.   if (structure_value_addr && ! structure_value_addr_parm
  2169.       && GET_CODE (struct_value_rtx) == REG)
  2170.     emit_insn (gen_rtx (USE, VOIDmode, struct_value_rtx));
  2171.  
  2172.   use_insns = gen_sequence ();
  2173.   end_sequence ();
  2174.  
  2175.   /* Figure out the register where the value, if any, will come back.  */
  2176.   valreg = 0;
  2177.   if (TYPE_MODE (TREE_TYPE (exp)) != VOIDmode
  2178.       && ! structure_value_addr)
  2179.     {
  2180.       if (pcc_struct_value)
  2181.     valreg = hard_libcall_value (Pmode);
  2182.       else
  2183.     valreg = hard_function_value (TREE_TYPE (exp), fndecl);
  2184.     }
  2185.  
  2186.   /* Generate the actual call instruction.  */
  2187.   /* This also has the effect of turning off any pop-inhibition
  2188.      done in expand_call.  */
  2189.   if (args_size.constant < 0)
  2190.     args_size.constant = 0;
  2191.   emit_call_1 (funexp, funtype, args_size.constant,
  2192.            FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  2193. #ifdef APPLE_C
  2194.            valreg, old_inhibit_defer_pop, use_insns, is_pascal, pascal_return_mode, fndecl);
  2195. #else
  2196.            valreg, old_inhibit_defer_pop, use_insns);
  2197. #endif /* APPLE_C */
  2198.  
  2199. /* ???  Nothing has been done here to record control flow
  2200.    when contained functions can do nonlocal gotos.  */
  2201.  
  2202.   /* For calls to `setjmp', etc., inform flow.c it should complain
  2203.      if nonvolatile values are live.  */
  2204.  
  2205.   if (is_setjmp)
  2206.     {
  2207.       emit_note (IDENTIFIER_POINTER (DECL_NAME (fndecl)), NOTE_INSN_SETJMP);
  2208.       current_function_calls_setjmp = 1;
  2209.     }
  2210.  
  2211.   /* Notice functions that cannot return.
  2212.      If optimizing, insns emitted below will be dead.
  2213.      If not optimizing, they will exist, which is useful
  2214.      if the user uses the `return' command in the debugger.  */
  2215.  
  2216.   if (fndecl && TREE_THIS_VOLATILE (fndecl))
  2217.     emit_barrier ();
  2218.  
  2219.   /* For calls to __builtin_new, note that it can never return 0.
  2220.      This is because a new handler will be called, and 0 it not
  2221.      among the numbers it is supposed to return.  */
  2222. #if 0
  2223.   if (is_builtin_new)
  2224.     emit_note (IDENTIFIER_POINTER (DECL_NAME (fndecl)), NOTE_INSN_BUILTIN_NEW);
  2225. #endif
  2226.  
  2227.   /* If value type not void, return an rtx for the value.  */
  2228.  
  2229.   /* If there are cleanups to be called, don't use a hard reg as target.  */
  2230.   if (cleanups_of_this_call != old_cleanups
  2231.       && target && REG_P (target)
  2232.       && REGNO (target) < FIRST_PSEUDO_REGISTER)
  2233.     target = 0;
  2234.  
  2235.   if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode
  2236.       || ignore)
  2237.     {
  2238.       target = const0_rtx;
  2239.     }
  2240.   else if (structure_value_addr)
  2241.     {
  2242.       if (target == 0 || GET_CODE (target) != MEM)
  2243.     target = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)),
  2244.               memory_address (BLKmode, structure_value_addr));
  2245.     }
  2246.   else if (pcc_struct_value)
  2247.     {
  2248.       valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)),
  2249.                     fndecl);
  2250.       if (target == 0)
  2251.     target = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)),
  2252.               copy_to_reg (valreg));
  2253.       else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
  2254.     emit_move_insn (target, gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)),
  2255.                      copy_to_reg (valreg)));
  2256.       else
  2257.     emit_block_move (target, gen_rtx (MEM, BLKmode, copy_to_reg (valreg)),
  2258.              expr_size (exp),
  2259.              TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  2260.     }
  2261.   else if (target && GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp)))
  2262.     {
  2263.       if (!rtx_equal_p (target, valreg))
  2264.     emit_move_insn (target, valreg);
  2265.       else
  2266.     /* This tells expand_inline_function to copy valreg to its target.  */
  2267.     emit_insn (gen_rtx (USE, VOIDmode, valreg));
  2268.     }
  2269.   else
  2270.     target = copy_to_reg (valreg);
  2271.  
  2272.   /* Perform all cleanups needed for the arguments of this call
  2273.      (i.e. destructors in C++).  */
  2274.   while (cleanups_of_this_call != old_cleanups)
  2275.     {
  2276.       expand_expr (TREE_VALUE (cleanups_of_this_call), 0, VOIDmode, 0);
  2277.       cleanups_of_this_call = TREE_CHAIN (cleanups_of_this_call);
  2278.     }
  2279.  
  2280.   /* If size of args is variable, restore saved stack-pointer value.  */
  2281.  
  2282.   if (old_stack_level)
  2283.     {
  2284.       emit_move_insn (stack_pointer_rtx, old_stack_level);
  2285.       pending_stack_adjust = old_pending_adj;
  2286.     }
  2287.  
  2288.   /* If call is cse'able, make appropriate pair of reg-notes around it.  */
  2289.   if (is_const)
  2290.     {
  2291.       rtx insn_first = NEXT_INSN (insn_before);
  2292.       rtx insn_last = get_last_insn ();
  2293.       rtx note = 0;
  2294.  
  2295.       /* Don't put the notes on if we don't have insns that can hold them.  */
  2296.       if ((GET_CODE (insn_first) == INSN
  2297.        || GET_CODE (insn_first) == CALL_INSN
  2298.        || GET_CODE (insn_first) == JUMP_INSN)
  2299.       && (GET_CODE (insn_last) == INSN
  2300.           || GET_CODE (insn_last) == CALL_INSN
  2301.           || GET_CODE (insn_last) == JUMP_INSN))
  2302.     {
  2303.       /* Construct an "equal form" for the value
  2304.          which mentions all the arguments in order
  2305.          as well as the function name.  */
  2306.       for (i = 0; i < num_actuals; i++)
  2307.         if (args[i].reg != 0 || is_const)
  2308.           note = gen_rtx (EXPR_LIST, VOIDmode, args[i].value, note);
  2309.       note = gen_rtx (EXPR_LIST, VOIDmode,
  2310.               XEXP (DECL_RTL (fndecl), 0), note);
  2311.  
  2312.       REG_NOTES (insn_last)
  2313.         = gen_rtx (EXPR_LIST, REG_EQUAL, note,
  2314.                gen_rtx (INSN_LIST, REG_RETVAL, insn_first,
  2315.                 REG_NOTES (insn_last)));
  2316.       REG_NOTES (insn_first)
  2317.         = gen_rtx (INSN_LIST, REG_LIBCALL, insn_last,
  2318.                REG_NOTES (insn_first));
  2319.     }
  2320.     }
  2321.  
  2322.   return target;
  2323. }
  2324.  
  2325. /* Return an rtx which represents a suitable home on the stack
  2326.    given TYPE, the type of the argument looking for a home.
  2327.    This is called only for BLKmode arguments.
  2328.  
  2329.    SIZE is the size needed for this target.
  2330.    ARGS_ADDR is the address of the bottom of the argument block for this call.
  2331.    OFFSET describes this parameter's offset into ARGS_ADDR.  It is meaningless
  2332.    if this machine uses push insns.  */
  2333.  
  2334. static rtx
  2335. target_for_arg (type, size, args_addr, offset)
  2336.      tree type;
  2337.      rtx size;
  2338.      rtx args_addr;
  2339.      struct args_size offset;
  2340. {
  2341.   rtx target;
  2342.   rtx offset_rtx = ARGS_SIZE_RTX (offset);
  2343.  
  2344.   /* We do not call memory_address if possible,
  2345.      because we want to address as close to the stack
  2346.      as possible.  For non-variable sized arguments,
  2347.      this will be stack-pointer relative addressing.  */
  2348.   if (GET_CODE (offset_rtx) == CONST_INT)
  2349.     target = plus_constant (args_addr, INTVAL (offset_rtx));
  2350.   else
  2351.     {
  2352.       /* I have no idea how to guarantee that this
  2353.      will work in the presence of register parameters.  */
  2354.       target = gen_rtx (PLUS, Pmode, args_addr, offset_rtx);
  2355.       target = memory_address (QImode, target);
  2356.     }
  2357.  
  2358.   return gen_rtx (MEM, BLKmode, target);
  2359. }
  2360.  
  2361. /* Store a single argument for a function call
  2362.    into the register or memory area where it must be passed.
  2363.    *ARG describes the argument value and where to pass it.
  2364.    ARGBLOCK is the address of the stack-block for all the arguments,
  2365.    or 0 on a machine where arguemnts are pushed individually.
  2366.    MAY_BE_ALLOCA nonzero says this could be a call to `alloca'
  2367.    so must be careful about how the stack is used.  */
  2368.  
  2369. static void
  2370. store_one_arg (arg, argblock, may_be_alloca)
  2371.      struct arg_data *arg;
  2372.      rtx argblock;
  2373.      int may_be_alloca;
  2374. {
  2375.   register tree pval = arg->tree_value;
  2376.   int used = 0;
  2377.  
  2378.   if (TREE_CODE (pval) == ERROR_MARK)
  2379.     return;
  2380.  
  2381.   if (arg->reg != 0 && arg->partial == 0)
  2382.     {
  2383.       /* Being passed entirely in a register.  */
  2384.       if (arg->value != 0)
  2385.     {
  2386.       if (GET_MODE (arg->value) == BLKmode)
  2387.         move_block_to_reg (REGNO (arg->reg), arg->value,
  2388.                    ((int_size_in_bytes (TREE_TYPE (pval))
  2389.                  + UNITS_PER_WORD - 1)
  2390.                 / UNITS_PER_WORD));
  2391.       else
  2392.         emit_move_insn (arg->reg, arg->value);
  2393.     }
  2394.       else
  2395.     store_expr (pval, arg->reg, 0);
  2396.  
  2397.       /* Don't allow anything left on stack from computation
  2398.      of argument to alloca.  */
  2399.       if (may_be_alloca)
  2400.     do_pending_stack_adjust ();
  2401.     }
  2402.   else if (TYPE_MODE (TREE_TYPE (pval)) != BLKmode)
  2403.     {
  2404.       register int size;
  2405.       rtx tem;
  2406.  
  2407.       /* Argument is a scalar, not entirely passed in registers.
  2408.      (If part is passed in registers, arg->partial says how much
  2409.      and emit_push_insn will take care of putting it there.)
  2410.      
  2411.      Push it, and if its size is less than the
  2412.      amount of space allocated to it,
  2413.      also bump stack pointer by the additional space.
  2414.      Note that in C the default argument promotions
  2415.      will prevent such mismatches.  */
  2416.  
  2417.       used = size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (pval)));
  2418.       /* Compute how much space the push instruction will push.
  2419.      On many machines, pushing a byte will advance the stack
  2420.      pointer by a halfword.  */
  2421. #ifdef PUSH_ROUNDING
  2422.       size = PUSH_ROUNDING (size);
  2423. #endif
  2424.       /* Compute how much space the argument should get:
  2425.      round up to a multiple of the alignment for arguments.  */
  2426.       if (none != FUNCTION_ARG_PADDING (TYPE_MODE (TREE_TYPE (pval)), const0_rtx))
  2427.     used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
  2428.          / (PARM_BOUNDARY / BITS_PER_UNIT))
  2429.         * (PARM_BOUNDARY / BITS_PER_UNIT));
  2430.  
  2431.       tem = arg->value;
  2432.       if (tem == 0)
  2433.     {
  2434.       tem = expand_expr (pval, 0, VOIDmode, 0);
  2435.       /* ANSI doesn't require a sequence point here,
  2436.          but PCC has one, so this will avoid some problems.  */
  2437.       emit_queue ();
  2438.     }
  2439.  
  2440.       /* Don't allow anything left on stack from computation
  2441.      of argument to alloca.  */
  2442.       if (may_be_alloca)
  2443.     do_pending_stack_adjust ();
  2444.  
  2445.       emit_push_insn (tem, TYPE_MODE (TREE_TYPE (pval)), 0, 0,
  2446.               arg->partial, arg->reg, used - size,
  2447.               argblock, ARGS_SIZE_RTX (arg->offset));
  2448.     }
  2449.   else if (arg->stack != 0)
  2450.     {
  2451.       /* BLKmode parm, not entirely passed in registers,
  2452.      and with space already allocated.  */
  2453.  
  2454.       tree sizetree = size_in_bytes (TREE_TYPE (pval));
  2455.       /* Round the size up to multiple of PARM_BOUNDARY bits.  */
  2456.       tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
  2457.       tree s2 = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
  2458.  
  2459.       /* Find out if the parm needs padding, and whether above or below.  */
  2460.       enum direction where_pad
  2461.     = FUNCTION_ARG_PADDING (TYPE_MODE (TREE_TYPE (pval)),
  2462.                 expand_expr (sizetree, 0, VOIDmode, 0));
  2463.  
  2464.       /* If it is padded below, adjust the stack address
  2465.      upward over the padding.  */
  2466.  
  2467.       if (where_pad == downward)
  2468.     {
  2469.       rtx offset_rtx;
  2470.       rtx address = XEXP (arg->stack, 0);
  2471.       struct args_size stack_offset;
  2472.  
  2473.       stack_offset.constant = 0;
  2474.       stack_offset.var = 0;
  2475.  
  2476.       /* Compute amount of padding.  */
  2477.       ADD_PARM_SIZE (stack_offset, s2);
  2478.       SUB_PARM_SIZE (stack_offset, sizetree);
  2479.       offset_rtx = ARGS_SIZE_RTX (stack_offset);
  2480.  
  2481.       /* Adjust the address to store at.  */
  2482.       if (GET_CODE (offset_rtx) == CONST_INT)
  2483.         address = plus_constant (address, INTVAL (offset_rtx));
  2484.       else
  2485.         {
  2486.           address = gen_rtx (PLUS, Pmode, address, offset_rtx);
  2487.           address = memory_address (QImode, address);
  2488.         }
  2489.       arg->stack = change_address (arg->stack, VOIDmode, address);
  2490.     }
  2491.  
  2492.       /* ARG->stack probably refers to the stack-pointer.  If so,
  2493.      stabilize it, in case stack-pointer changes during evaluation.  */
  2494.       if (reg_mentioned_p (stack_pointer_rtx, arg->stack))
  2495.     arg->stack = change_address (arg->stack, VOIDmode,
  2496.                      copy_to_reg (XEXP (arg->stack, 0)));
  2497.       /* BLKmode argument that should go in a prespecified stack location.  */
  2498.       if (arg->value == 0)
  2499.     /* Not yet computed => compute it there.  */
  2500.     /* ??? This should be changed to tell expand_expr
  2501.        that it can store directly in the target.  */
  2502.     arg->value = store_expr (arg->tree_value, arg->stack, 0);
  2503.       else if (arg->value != arg->stack)
  2504.     /* It was computed somewhere, but not where we wanted.
  2505.        For example, the value may have come from an official
  2506.        local variable or parameter.  In that case, expand_expr
  2507.        does not fill our suggested target.  */
  2508.     emit_block_move (arg->stack, arg->value, ARGS_SIZE_RTX (arg->size),
  2509.              TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT);
  2510.  
  2511.       /* Now, if this value wanted to be partly in registers,
  2512.      move the value from the stack to the registers
  2513.      that are supposed to hold the values.  */
  2514.       if (arg->partial > 0)
  2515.     move_block_to_reg (REGNO (arg->reg), arg->stack, arg->partial);
  2516.     }
  2517.   else
  2518.     {
  2519.       /* BLKmode, at least partly to be pushed.  */
  2520.  
  2521.       register rtx tem
  2522.     = arg->value ? arg->value : expand_expr (pval, 0, VOIDmode, 0);
  2523.       register int excess;
  2524.       rtx size_rtx;
  2525.  
  2526.       /* Pushing a nonscalar.
  2527.      If part is passed in registers, arg->partial says how much
  2528.      and emit_push_insn will take care of putting it there.  */
  2529.  
  2530.       /* Round its size up to a multiple
  2531.      of the allocation unit for arguments.  */
  2532.  
  2533.       if (arg->size.var != 0)
  2534.     {
  2535.       excess = 0;
  2536.       size_rtx = ARGS_SIZE_RTX (arg->size);
  2537.     }
  2538.       else
  2539.     {
  2540.       register tree size = size_in_bytes (TREE_TYPE (pval));
  2541.       /* PUSH_ROUNDING has no effect on us, because
  2542.          emit_push_insn for BLKmode is careful to avoid it.  */
  2543.       excess = (arg->size.constant - TREE_INT_CST_LOW (size)
  2544.             + arg->partial * UNITS_PER_WORD);
  2545.       size_rtx = expand_expr (size, 0, VOIDmode, 0);
  2546.     }
  2547.  
  2548.       if (arg->stack)
  2549.     abort ();
  2550.  
  2551.       emit_push_insn (tem, TYPE_MODE (TREE_TYPE (pval)), size_rtx,
  2552.               TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT,
  2553.               arg->partial, arg->reg, excess, argblock,
  2554.               ARGS_SIZE_RTX (arg->offset));
  2555.     }
  2556.  
  2557.   /* Once we have pushed something, pops can't safely
  2558.      be deferred during the rest of the arguments.  */
  2559.   NO_DEFER_POP;
  2560. }
  2561.  
  2562. /* Expand conditional expressions.  */
  2563.  
  2564. /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
  2565.    LABEL is an rtx of code CODE_LABEL, in this function and all the
  2566.    functions here.  */
  2567.  
  2568. void
  2569. jumpifnot (exp, label)
  2570.      tree exp;
  2571.      rtx label;
  2572. {
  2573.   do_jump (exp, label, 0);
  2574. }
  2575.  
  2576. /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
  2577.  
  2578. void
  2579. jumpif (exp, label)
  2580.      tree exp;
  2581.      rtx label;
  2582. {
  2583.   do_jump (exp, 0, label);
  2584. }
  2585.  
  2586. /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
  2587.    the result is zero, or IF_TRUE_LABEL if the result is one.
  2588.    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
  2589.    meaning fall through in that case.
  2590.  
  2591.    This function is responsible for optimizing cases such as
  2592.    &&, || and comparison operators in EXP.  */
  2593.  
  2594. void
  2595. do_jump (exp, if_false_label, if_true_label)
  2596.      tree exp;
  2597.      rtx if_false_label, if_true_label;
  2598. {
  2599.   register enum tree_code code = TREE_CODE (exp);
  2600.   /* Some cases need to create a label to jump to
  2601.      in order to properly fall through.
  2602.      These cases set DROP_THROUGH_LABEL nonzero.  */
  2603.   rtx drop_through_label = 0;
  2604.   rtx temp;
  2605.   rtx comparison = 0;
  2606.  
  2607.   emit_queue ();
  2608.  
  2609.   switch (code)
  2610.     {
  2611.     case ERROR_MARK:
  2612.       break;
  2613.  
  2614.     case INTEGER_CST:
  2615.       temp = integer_zerop (exp) ? if_false_label : if_true_label;
  2616.       if (temp)
  2617.     emit_jump (temp);
  2618.       break;
  2619.  
  2620.     case ADDR_EXPR:
  2621.       /* The address of something can never be zero.  */
  2622.       if (if_true_label)
  2623.     emit_jump (if_true_label);
  2624.       break;
  2625.  
  2626.     case NOP_EXPR:
  2627.       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
  2628.       break;
  2629.  
  2630.     case TRUTH_NOT_EXPR:
  2631.       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
  2632.       break;
  2633.  
  2634.     case TRUTH_ANDIF_EXPR:
  2635.       if (if_false_label == 0)
  2636.     if_false_label = drop_through_label = gen_label_rtx ();
  2637.       do_jump (TREE_OPERAND (exp, 0), if_false_label, 0);
  2638.       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
  2639.       break;
  2640.  
  2641.     case TRUTH_ORIF_EXPR:
  2642.       if (if_true_label == 0)
  2643.     if_true_label = drop_through_label = gen_label_rtx ();
  2644.       do_jump (TREE_OPERAND (exp, 0), 0, if_true_label);
  2645.       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
  2646.       break;
  2647.  
  2648.     case COMPOUND_EXPR:
  2649.       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
  2650.       emit_queue ();
  2651.       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
  2652.       break;
  2653.  
  2654.     case COND_EXPR:
  2655.       {
  2656.     register rtx label1 = gen_label_rtx ();
  2657.     drop_through_label = gen_label_rtx ();
  2658.     do_jump (TREE_OPERAND (exp, 0), label1, 0);
  2659.     /* Now the THEN-expression.  */
  2660.     do_jump (TREE_OPERAND (exp, 1),
  2661.          if_false_label ? if_false_label : drop_through_label,
  2662.          if_true_label ? if_true_label : drop_through_label);
  2663.     emit_label (label1);
  2664.     /* Now the ELSE-expression.  */
  2665.     do_jump (TREE_OPERAND (exp, 2),
  2666.          if_false_label ? if_false_label : drop_through_label,
  2667.          if_true_label ? if_true_label : drop_through_label);
  2668.       }
  2669.       break;
  2670.  
  2671.     case EQ_EXPR:
  2672.       comparison = compare (exp, EQ, EQ, EQ, EQ);
  2673.       break;
  2674.  
  2675.     case NE_EXPR:
  2676.       comparison = compare (exp, NE, NE, NE, NE);
  2677.       break;
  2678.  
  2679.     case LT_EXPR:
  2680.       comparison = compare (exp, LT, LTU, GT, GTU);
  2681.       break;
  2682.  
  2683.     case LE_EXPR:
  2684.       comparison = compare (exp, LE, LEU, GE, GEU);
  2685.       break;
  2686.  
  2687.     case GT_EXPR:
  2688.       comparison = compare (exp, GT, GTU, LT, LTU);
  2689.       break;
  2690.  
  2691.     case GE_EXPR:
  2692.       comparison = compare (exp, GE, GEU, LE, LEU);
  2693.       break;
  2694.  
  2695.     default:
  2696.       temp = expand_expr (exp, 0, VOIDmode, 0);
  2697.       /* Copy to register to avoid generating bad insns by cse
  2698.      from (set (mem ...) (arithop))  (set (cc0) (mem ...)).  */
  2699.       if (!cse_not_expected && GET_CODE (temp) == MEM)
  2700.     temp = copy_to_reg (temp);
  2701.       do_pending_stack_adjust ();
  2702.       {
  2703.     rtx zero = CONST0_RTX (GET_MODE (temp));
  2704.  
  2705.     if (GET_CODE (temp) == CONST_INT)
  2706.       comparison = compare_constants (NE, 0,
  2707.                       INTVAL (temp), 0, BITS_PER_WORD);
  2708.     else if (GET_MODE (temp) != VOIDmode)
  2709.       comparison = compare1 (temp, zero, NE, NE, 0, GET_MODE (temp));
  2710.     else
  2711.       abort ();
  2712.       }
  2713.     }
  2714.  
  2715.   /* Do any postincrements in the expression that was tested.  */
  2716.   emit_queue ();
  2717.  
  2718.   /* If COMPARISON is nonzero here, it is an rtx that can be substituted
  2719.      straight into a conditional jump instruction as the jump condition.
  2720.      Otherwise, all the work has been done already.  */
  2721.  
  2722.   if (comparison == const1_rtx)
  2723.     {
  2724.       if (if_true_label)
  2725.     emit_jump (if_true_label);
  2726.     }
  2727.   else if (comparison == const0_rtx)
  2728.     {
  2729.       if (if_false_label)
  2730.     emit_jump (if_false_label);
  2731.     }
  2732.   else if (comparison)
  2733.     {
  2734.       if (if_true_label)
  2735.     {
  2736.       if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
  2737.         emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label));
  2738.       else
  2739.         abort ();
  2740.  
  2741.       if (if_false_label)
  2742.         emit_jump (if_false_label);
  2743.     }
  2744.       else if (if_false_label)
  2745.     {
  2746.       rtx pat;
  2747.  
  2748.       if (bcc_gen_fctn[(int) GET_CODE (comparison)] == 0)
  2749.         abort ();
  2750.  
  2751.       pat = (*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_false_label);
  2752.       /* Now invert the sense of the jump by exchanging the two arms
  2753.          of each IF_THEN_ELSE.  Note that inverting the condition
  2754.          would be incorrect for IEEE floating point with nans!  */
  2755.       if (GET_CODE (pat) == SEQUENCE)
  2756.         {
  2757.           int i;
  2758.           /* We can invert a sequence if the only jump is at the end.  */
  2759.           for (i = 0; i < (int) (XVECLEN (pat, 0) - 1); i++)
  2760.         if (GET_CODE (XVECEXP (pat, 0, i)) == JUMP_INSN)
  2761.           abort ();
  2762.           invert_exp (PATTERN (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)),
  2763.               0, 0);
  2764.         }
  2765.       else
  2766.         invert_exp (pat, 0, 0);
  2767.  
  2768.       emit_jump_insn (pat);
  2769.     }
  2770.     }
  2771.  
  2772.   if (drop_through_label)
  2773.     emit_label (drop_through_label);
  2774. }
  2775.  
  2776. /* Compare two integer constant rtx's, OP0 and OP1.
  2777.    The comparison operation is OPERATION.
  2778.    Return an rtx representing the value 1 or 0.
  2779.    WIDTH is the width in bits that is significant.  */
  2780.  
  2781. static rtx
  2782. compare_constants (operation, unsignedp, op0, op1, width)
  2783.      enum rtx_code operation;
  2784.      int unsignedp;
  2785.      int op0, op1;
  2786.      int width;
  2787. {
  2788.   int val;
  2789.  
  2790.   /* Sign-extend or zero-extend the operands to a full word
  2791.      from an initial width of WIDTH bits.  */
  2792.   if (width < HOST_BITS_PER_INT)
  2793.     {
  2794.       op0 &= (1 << width) - 1;
  2795.       op1 &= (1 << width) - 1;
  2796.  
  2797.       if (! unsignedp)
  2798.     {
  2799.       if (op0 & (1 << (width - 1)))
  2800.         op0 |= ((-1) << width);
  2801.       if (op1 & (1 << (width - 1)))
  2802.         op1 |= ((-1) << width);
  2803.     }
  2804.     }
  2805.  
  2806.   switch (operation)
  2807.     {
  2808.     case EQ:
  2809.       val = op0 == op1;
  2810.       break;
  2811.  
  2812.     case NE:
  2813.       val = op0 != op1;
  2814.       break;
  2815.  
  2816.     case GT:
  2817.     case GTU:
  2818.       val = op0 > op1;
  2819.       break;
  2820.  
  2821.     case LT:
  2822.     case LTU:
  2823.       val = op0 < op1;
  2824.       break;
  2825.  
  2826.     case GE:
  2827.     case GEU:
  2828.       val = op0 >= op1;
  2829.       break;
  2830.  
  2831.     case LE:
  2832.     case LEU:
  2833.       val = op0 <= op1;
  2834.     }
  2835.  
  2836.   return val ? const1_rtx : const0_rtx;
  2837. }
  2838.  
  2839. /* Generate code for a comparison expression EXP
  2840.    (including code to compute the values to be compared)
  2841.    and set (CC0) according to the result.
  2842.    SIGNED_FORWARD should be the rtx operation for this comparison for
  2843.    signed data; UNSIGNED_FORWARD, likewise for use if data is unsigned.
  2844.    SIGNED_REVERSE and UNSIGNED_REVERSE are used if it is desirable
  2845.    to interchange the operands for the compare instruction.
  2846.  
  2847.    We force a stack adjustment unless there are currently
  2848.    things pushed on the stack that aren't yet used.  */
  2849.  
  2850. static rtx
  2851. compare (exp, signed_forward, unsigned_forward,
  2852.      signed_reverse, unsigned_reverse)
  2853.      register tree exp;
  2854.      enum rtx_code signed_forward, unsigned_forward;
  2855.      enum rtx_code signed_reverse, unsigned_reverse;
  2856. {
  2857.  
  2858.   register rtx op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
  2859.   register rtx op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
  2860.   register enum machine_mode mode = GET_MODE (op0);
  2861.   int unsignedp;
  2862.  
  2863.   /* If one operand is 0, make it the second one.  */
  2864.  
  2865.   if (op0 == const0_rtx
  2866.       || (GET_MODE_CLASS (mode) == MODE_FLOAT && op0 == CONST0_RTX (mode)))
  2867.     {
  2868.       rtx tem = op0;
  2869.       op0 = op1;
  2870.       op1 = tem;
  2871.       signed_forward = signed_reverse;
  2872.       unsigned_forward = unsigned_reverse;
  2873.     }
  2874.  
  2875.   if (flag_force_mem)
  2876.     {
  2877.       op0 = force_not_mem (op0);
  2878.       op1 = force_not_mem (op1);
  2879.     }
  2880.  
  2881.   do_pending_stack_adjust ();
  2882.  
  2883.   unsignedp = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)))
  2884.            || TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1))));
  2885.  
  2886.   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
  2887.     return compare_constants (signed_forward, unsignedp,
  2888.                   INTVAL (op0), INTVAL (op1),
  2889.                   GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))));
  2890.  
  2891.   emit_cmp_insn (op0, op1,
  2892.          (mode == BLKmode) ? expr_size (TREE_OPERAND (exp, 0)) : 0,
  2893.          unsignedp,
  2894.          TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  2895.  
  2896.   return gen_rtx ((unsignedp ? unsigned_forward : signed_forward),
  2897.           VOIDmode, cc0_rtx, const0_rtx);
  2898. }
  2899.  
  2900. /* Like compare but expects the values to compare as two rtx's.
  2901.    The decision as to signed or unsigned comparison must be made by the caller.
  2902.    BLKmode is not allowed.  */
  2903.  
  2904. static rtx
  2905. compare1 (op0, op1, forward_op, reverse_op, unsignedp, mode)
  2906.      register rtx op0, op1;
  2907.      enum rtx_code forward_op, reverse_op;
  2908.      int unsignedp;
  2909.      enum machine_mode mode;
  2910. {
  2911.   /* If one operand is 0, make it the second one.  */
  2912.  
  2913.   if (op0 == const0_rtx
  2914.       || (GET_MODE_CLASS (mode) == MODE_FLOAT && op0 == CONST0_RTX (mode)))
  2915.     {
  2916.       rtx tem = op0;
  2917.       op0 = op1;
  2918.       op1 = tem;
  2919.       forward_op = reverse_op;
  2920.     }
  2921.  
  2922.   if (flag_force_mem)
  2923.     {
  2924.       op0 = force_not_mem (op0);
  2925.       op1 = force_not_mem (op1);
  2926.     }
  2927.  
  2928.   do_pending_stack_adjust ();
  2929.  
  2930.   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
  2931.     return compare_constants (forward_op, unsignedp,
  2932.                   INTVAL (op0), INTVAL (op1),
  2933.                   GET_MODE_BITSIZE (mode));
  2934.  
  2935.   emit_cmp_insn (op0, op1, 0, unsignedp, 0);
  2936.  
  2937.   return gen_rtx (forward_op, VOIDmode, cc0_rtx, const0_rtx);
  2938. }
  2939.  
  2940. /* Generate code to calculate EXP using a store-flag instruction
  2941.    and return an rtx for the result.
  2942.    If TARGET is nonzero, store the result there if convenient.
  2943.  
  2944.    Return zero if there is no suitable set-flag instruction
  2945.    available on this machine.  */
  2946.  
  2947. static rtx
  2948. do_store_flag (exp, target, mode)
  2949.      tree exp;
  2950.      rtx target;
  2951.      enum machine_mode mode;
  2952. {
  2953.   register enum tree_code code = TREE_CODE (exp);
  2954.   register rtx comparison = 0;
  2955.   enum machine_mode compare_mode;
  2956.   rtx prev_insn = get_last_insn ();
  2957.   enum insn_code icode;
  2958.  
  2959.   switch (code)
  2960.     {
  2961. #ifdef HAVE_seq
  2962.     case EQ_EXPR:
  2963.       if (HAVE_seq)
  2964.     {
  2965.       comparison = compare (exp, EQ, EQ, EQ, EQ);
  2966.       icode = CODE_FOR_seq;
  2967.       compare_mode = insn_operand_mode[(int) CODE_FOR_seq][0];
  2968.     }
  2969.       break;
  2970. #endif
  2971.  
  2972. #ifdef HAVE_sne
  2973.     case NE_EXPR:
  2974.       if (HAVE_sne)
  2975.     {
  2976.       comparison = compare (exp, NE, NE, NE, NE);
  2977.       icode = CODE_FOR_sne;
  2978.       compare_mode = insn_operand_mode[(int) CODE_FOR_sne][0];
  2979.     }
  2980.       break;
  2981. #endif
  2982.  
  2983. #if defined (HAVE_slt) && defined (HAVE_sltu) && defined (HAVE_sgt) && defined (HAVE_sgtu)
  2984.     case LT_EXPR:
  2985.       if (HAVE_slt && HAVE_sltu && HAVE_sgt && HAVE_sgtu)
  2986.     {
  2987.       comparison = compare (exp, LT, LTU, GT, GTU);
  2988.       icode = CODE_FOR_slt;
  2989.       compare_mode = insn_operand_mode[(int) CODE_FOR_slt][0];
  2990.     }
  2991.       break;
  2992.  
  2993.     case GT_EXPR:
  2994.       if (HAVE_slt && HAVE_sltu && HAVE_sgt && HAVE_sgtu)
  2995.     {
  2996.       comparison = compare (exp, GT, GTU, LT, LTU);
  2997.       icode = CODE_FOR_slt;
  2998.       compare_mode = insn_operand_mode[(int) CODE_FOR_slt][0];
  2999.     }
  3000.       break;
  3001. #endif
  3002.  
  3003. #if defined (HAVE_sle) && defined (HAVE_sleu) && defined (HAVE_sge) && defined (HAVE_sgeu)
  3004.     case LE_EXPR:
  3005.       if (HAVE_sle && HAVE_sleu && HAVE_sge && HAVE_sgeu)
  3006.     {
  3007.       comparison = compare (exp, LE, LEU, GE, GEU);
  3008.       icode = CODE_FOR_sle;
  3009.       compare_mode = insn_operand_mode[(int) CODE_FOR_sle][0];
  3010.     }
  3011.       break;
  3012.  
  3013.     case GE_EXPR:
  3014.       if (HAVE_sle && HAVE_sleu && HAVE_sge && HAVE_sgeu)
  3015.     {
  3016.       comparison = compare (exp, GE, GEU, LE, LEU);
  3017.       icode = CODE_FOR_sle;
  3018.       compare_mode = insn_operand_mode[(int) CODE_FOR_sle][0];
  3019.     }
  3020.       break;
  3021. #endif
  3022.     }
  3023.   if (comparison == 0)
  3024.     return 0;
  3025.  
  3026.   if (target == 0 || GET_MODE (target) != mode
  3027.       /* Don't use specified target unless the insn can handle it.  */
  3028.       || ! (*insn_operand_predicate[(int) icode][0]) (target, mode)
  3029.       /* When modes don't match, don't use specified target,
  3030.      because it might be the same as an operand,
  3031.      and then the CLOBBER output below would screw up.  */
  3032.       || (mode != compare_mode && GET_CODE (comparison) != CONST_INT))
  3033.     target = gen_reg_rtx (mode);
  3034.  
  3035.   /* Store the comparison in its proper mode.  */
  3036.   if (GET_CODE (comparison) == CONST_INT)
  3037.     emit_move_insn (target, comparison);
  3038.   else if (GET_MODE (target) != compare_mode)
  3039.     {
  3040.       /* We want a different mode: store result in its natural mode.
  3041.      Combine the mode conversion with the truncation we must do anyway.  */
  3042.       /* Put a CLOBBER before the compare, so we don't come between
  3043.      the compare and the insn that uses the result.  */
  3044.       emit_insn_after (gen_rtx (CLOBBER, VOIDmode, target), prev_insn);
  3045.       emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)])
  3046.          (gen_rtx (SUBREG, compare_mode, target, 0)));
  3047.       /* If the desired mode is wider than what we got,
  3048.      use an AND to convert it, but not if we will do one anyway.  */
  3049. #if STORE_FLAG_VALUE == 1
  3050.       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (compare_mode))
  3051.     expand_bit_and (mode, target, const1_rtx, target);
  3052. #endif
  3053.     }
  3054.   else
  3055.     emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)]) (target));
  3056.  
  3057. #if STORE_FLAG_VALUE != 1
  3058. #if STORE_FLAG_VALUE & 1
  3059.   expand_bit_and (mode, target, const1_rtx, target);
  3060. #else
  3061.   expand_shift (RSHIFT_EXPR, mode, target,
  3062.         build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
  3063.         target, TRUE);
  3064. #endif
  3065. #endif
  3066.   return target;
  3067. }
  3068.  
  3069. /* Generate a tablejump instruction (used for switch statements).  */
  3070.  
  3071. #ifdef HAVE_tablejump
  3072.  
  3073. /* INDEX is the value being switched on, with the lowest value
  3074.    in the table already subtracted.
  3075.    RANGE is the length of the jump table.
  3076.    TABLE_LABEL is a CODE_LABEL rtx for the table itself.
  3077.  
  3078.    DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
  3079.    index value is out of range.  */
  3080.  
  3081. void
  3082. do_tablejump (index, range, table_label, default_label)
  3083.      rtx index, range, table_label, default_label;
  3084. {
  3085.   register rtx temp;
  3086.  
  3087.   emit_cmp_insn (range, index, 0, 0, 0);
  3088.   emit_jump_insn (gen_bltu (default_label));
  3089.   /* If flag_force_addr were to affect this address
  3090.      it could interfere with the tricky assumptions made
  3091.      about addresses that contain label-refs,
  3092.      which may be valid only very near the tablejump itself.  */
  3093.   index = memory_address_noforce
  3094.     (CASE_VECTOR_MODE,
  3095.      gen_rtx (PLUS, Pmode,
  3096.           gen_rtx (MULT, Pmode, index,
  3097.                gen_rtx (CONST_INT, VOIDmode,
  3098.                 GET_MODE_SIZE (CASE_VECTOR_MODE))),
  3099.           gen_rtx (LABEL_REF, VOIDmode, table_label)));
  3100.   temp = gen_reg_rtx (CASE_VECTOR_MODE);
  3101.   convert_move (temp, gen_rtx (MEM, CASE_VECTOR_MODE, index), 0);
  3102.  
  3103.   emit_jump_insn (gen_tablejump (temp, table_label));
  3104. }
  3105.  
  3106. #endif /* HAVE_tablejump */
  3107.  
  3108. int init_expr2()
  3109. #define INIT_EXPR
  3110. {
  3111. #include "init.c"
  3112. }